Copyright: Copyright « 1988-1998 by TransEra Corp.
Citation: Copyright « 1988-1998 by TransEra Corp.


Contents
User's Guide

Chapter 1	Getting Started

Chapter 2	Porting HP BASIC Programs to HTBasic

Chapter 3	Language Elements

Chapter 4	Program Flow Control

Chapter 5	Mathematics

Chapter 6	Graphics

Chapter 7	General Input and Output

Chapter 8	CRT, Keyboard and Printer

Chapter 9	Files

Chapter 10	IEEE-488 Interface Bus

Chapter 11	Serial (RS-232) I/O

Chapter 12	Other I/O Destinations/Sources

Chapter 13	International Language Support

Other Manuals	Reference Manual 	Installing and Using Manual

Copyright ® 1988-1998 by TransEra Corp.


Chapter 1 CON
Contents
Chapter 1, Getting Started

Chapter 1	Getting Started

High Tech Basic

Installation Manual

Reference Manual

This Manual

Language Definition

Input and Output

Advanced Topics

Using the Integrated Environment

Display Screen

Output Area

Control Characters

Display Enhancements Characters

Display Line

Input Line

Message Line

Softkey Menu

Customizing the Environment

Program Development

Program Documentation

Live Keyboard Execution

HELP Command

EDIT Mode

SUB Mode

Save Changes

Starting Edit Mode

Terminating Edit Mode

Controlling the Cursor

Syntax Checking

Inserting Lines

Deleting Lines

Immediate Commands

Associated Commands

FIND Command

CHANGE Command

COPYLINES Command

MOVELINES Command

INDENT Command

REN Command

DEL Command

SCRATCH Command

XREF Command

SECURE Command

Alternate Editing Techniques

Using an Editor

Running and Stopping Programs

STOP

QUIT

Debugging Programs

Pausing the Program

Continue

STEP

TRACE Statement

Saving Programs

STORE Statement

SAVE Statement

Loading Programs

GET Statement

LOAD Statement

Subprograms

LOADSUB Statement

DELSUB Statement


Chapter 2 CON
Contents
Chapter 2, Porting HP BASIC Programs to HTBasic

Chapter 2	Porting HP BASIC Programs to HTBasic

Compatibility

Hardware Differences

Disk Drives

Softkey Layout

A New Backspace

Series 300 Bit-Mapped (CRTB) Displays

9836C (CRTA) Displays

Other Video Circuitry Differences

Expanded Memory

Processor

Speed

Clock

HP-IB/IEEE-488

Character Set

Shared Resource Manager (SRM)

Miscellaneous Differences

HP ASCII File Problem

File Systems

LIF ASCII vs. Ordinary ASCII

DOS (FAT) File System

DOS (FAT) File Specifier

DOS Directory Path

DOS File Types and Access Capabilities

DOS Devices

DOS Wildcards

Keyword Differences

ALLOCATE

ASSIGN

ATN2

BEEP

BINEQV/BINIMP

BLOAD/BSTORE

BUFFER

CAT

CDIAL

CHECKREAD

CHGRP and CHOWN

CINT

COMMAND$

CONFIGURE

CONTROL/STATUS

COPY

CREATE

CREATE DIR

DEF FN

DELSUB

DUMP

EDIT

ENABLE INTR

ENVIRON$

ERRDS

ERRM$

ERRN

EXECUTE

FIX

FRACT

FRE

GESCAPE

GET

GLOAD/GSTORE

GRAPHICS INPUT IS

HELP

HIL

IMAGE

INITIALIZE

INP/INPW

KBD CMODE

LEXICAL ORDER

LINE TYPE

LIST BIN

LOAD

LOAD BIN

LOADSUB

MASS STORAGE IS

OUT/OUTW

OUTPUT KBD

PERMIT

PHYREC, Phyread, Phywrite

PLOTTER IS

PRINT

PRINT LABEL and READ LABEL

PROTECT

PRT

PURGE

QUIT

READIO/WRITEIO

RENAME

SAVE

SCRATCH BIN

SEPARATE ALPHA

SET ALPHA/DISPLAY MASK

SET CHR

SET TIME/TIMEDATE

SOUND

STATUS

STORE

STORE SYSTEM

SYMBOL

SYSBOOT

SYSTEM$

TIMEZONE

TRANSFER

WRITEIO

XREF


Chapter 3 CON
Contents
Chapter 3, Language Elements

Chapter 3	Language Elements

Program lines

Line Numbers

Line Labels

Statements

Comments

Keywords

Program Contexts

Main Context

Subprogram Contexts

User Defined Function Contexts

CSUB Contexts

Integer Numbers

Real Numbers

Cautions

REAL Comparisons

FOR Loops

Definition

Complex Numbers

Strings

I/O Paths

Constants

Numeric Constants

String Constants

Variables

Variable Names

Variable Types

Variable Scope

Array Variables

Declaration

String Arrays

Examples


Chapter 4 CON
Contents
Chapter 4, Program Flow Control

Chapter 4	Program Flow Control

Program Execution

The Paused State

The Stopped State

Returning to the Operating System

Branching

Conditional Statements

ON...GOTO Statement

ON...GOSUB Statement

SELECT and CASE Statements

Loops

FOR Loops

Other Loop Types

Subroutines

Program Contexts

Main Context

Subprogram Contexts

Subprogram Pointers

User Defined Function Contexts

CSUB Contexts

Interrupting Program Flow

Priority

Global and Local Aspects

Disabling Events

Error Handling

Defining an Error Handler

The Error Handler Routine

EXECUTE Statement

DOS Version Usage Notes

Windows Version Usage Notes

UNIX Usage Notes


Chapter 5 CON
Contents
Chapter 5, Mathematics

Chapter 5	Mathematics

Numeric Expressions

String Expressions

Matrix Expressions

Operands

Operators

Arithmetic

Binary

Conversions

Date/Time

Environment

Error

I/O Functions

Logical

Relational

String Functions

Transcendental and Trigonometric

Other Functions

User Defined Functions

Automatic Conversions

Execution Precedence

Matrix Operators

Matrix Operators with Matrix Result

Matrix Operators with Scalar Result

Matrix Sub-array Assignments

Matrix Searching

Matrix Inversion

Complex Operators

Extended Statements and Operators

Added Statements and Operators

SYSTEM$

AVAILABLE MEMORY

CRT ID

DISP LINE

DUMP DEVICE IS

GRAPHICS INPUT IS

KBD LINE

KEYBOARD LANGUAGE

LEXICAL ORDER IS

MASS MEMORY

MASS STORAGE IS or MSI

PLOTTER IS

PRINTALL IS

PROCESS ID

PRINTER IS

SERIAL NUMBER

SYSTEM ID

SYSTEM PRIORITY

TIMEZONE IS

TRIG MODE

VERSION:BASIC

VERSION:HTB

VERSION:OS

VERSION:bin-name

WILDCARDS

WINDOW SYSTEM


Chapter 6 CON
Contents
Chapter 6, Graphics

Chapter 6	Graphics

Simple Graphics Statements

GINIT Statement

GCLEAR and CLS Statements

Graphics Coordinate System

MOVE and DRAW Statements

PLOT Statement

PENUP Statement

User Defined Graphic Units

VIEWPORT Statement

CLIP Statement

SHOW Statement

WINDOW Statement

WINDOW and VIEWPORT Effects

Annotating Charts and Graphs

AXES and GRID Statements

FRAME Statement

LABEL Statement

CSIZE Statement

LDIR Statement

LORG Statement

Graphic Attributes

LINE TYPE Statement

Color Graphics

HSL Color Space

RGB Color Space

Pen Numbers

COLOR MAP Mode

SET PEN Statement

GESCAPE Statement

Code 1

Code 2

Code 3

Codes 4 & 5

Code 6

Code 7

Codes 100 & 101

Code 102

Code 103

Code 104

Code 105

Code 106

Incremental and Relative Graphics

IMOVE Statement

IDRAW Statement

IPLOT Statement

RPLOT Statement

Arcs, Circles, and Rectangles

POLYGON and POLYLINE Statements

RECTANGLE Statement

User Defined Symbols

AREA Fill Styles and Colors

AREA Statement

FILL and EDGE Options

Array Specified Pen Control

AREA Color

FILL and EDGE

Graphics Rotation

PDIR Statement

PIVOT Statement

Screen Raster Images

Full Screen

Rectangular Blocks

Screen Storage Formats

CGA & Hercules Graphics Cards

EGA, VGA & SuperVGA 16 Color Graphics Cards

Super VGA 256 Color Graphics Cards

S3 & ATI Graphics Cards16 Color Modes

S3 & ATI Graphics Cards256 Color Modes

Screen Dumps

DUMP ALPHA Statement

DUMP GRAPHICS Statement

DUMP DEVICE IS Statement

Partial Screen Dumps

Graphics Devices

PLOTTER IS Statement

GSEND Statement

GRAPHICS INPUT IS Statement

READ LOCATOR Statement

SET LOCATOR Statement

WHERE Statement

Tracking Graphics Input

SET ECHO Statement

TRACK and DIGITIZE Statements

Mixing Output and Input Devices

Separate and Merged Alpha

Merged Alpha

Separate Alpha

Porting Issues


Chapter 7 CON
Contents
Chapter 7, General Input and Output

Chapter 7	General Input and Output

ASSIGN Statement

Syntax

Devices

Files

Pipes

Buffers

Attributes

FORMAT Options

BYTE and WORD

EOL

APPEND

RETURN

Closing an I/O Path

OUTPUT Statement

Numeric Items

String Items

End of Line

END

ENTER Statement

Numeric Items

String Items

Statement Termination

Formatted I/O

IMAGE Interpretation

Syntax

OUTPUT, etc.

ENTER

Creating Format Strings

PRINT Examples

ENTER Example

END

TRANSFER

Examples

Support

Buffers

Transfer Type

Transfer Method

Transfer Termination

ON EOR and ON EOT

Termination

Hanging and Premature Termination

Outbound TRANSFER

Inbound TRANSFER

STATUS, CONTROL, READIO, and WRITEIO

CONTROL Statement

STATUS Statement and Function

Device I/O Path Registers

ASCII File I/O Path Registers

BDAT and Ordinary file I/O Path Registers

BUFFER I/O Path Registers

Pipe I/O Path Registers

Interface Hardware Registers

READIO Function

WRITEIO Statement

PEEK/POKE Memory

IN/OUT Operations

Locating a Numeric Variable

Calling Assembly Language Subroutines

Interrupts

ON INTR Statement

OFF INTR Statement

Enabling and Disabling Interrupts

Interrupt Routines

Specialized I/O Statements

READ/DATA Statements

BEEP Statement

PC Usage Notes

UNIX Usage Notes


Chapter 8 CON
Contents

Chapter 8, CRT, Keyboard, and Printer

Chapter 8	CRT, Keyboard, and Printer

Display (CRT)

Display Organization

OUTPUT CRT

PRINT

DISP Statement

PRINT and DISP Statements

Attributes and Colors

Display Functions

CRT Related Statements

CONTROL/STATUS CRT

ENTER CRT

Keyboard (KBD)

ENTER KBD

INPUT Statement

LINPUT Statement

OUTPUT KBD

CONTROL/STATUS KBD

Using a Printer

Accessed Directly

Using the Print Daemon

The PRT function

The PRINTER IS device

The PRINTALL IS device

CRT and KBD Registers

CRT CONTROL Registers

CRT STATUS Registers

KBD CONTROL Registers

KBD STATUS Registers


Chapter 9 CON
Contents
Chapter 9,Files

Chapter 9	Files

File Management Commands

ASSIGN

CAT

CHGRP and CHOWN

COPY

CREATE

INITIALIZE

LINK

LOCK and UNLOCK

MASS STORAGE IS

PERMIT

PRINT LABEL and READ LABEL

PROTECT

PURGE

RENAME

RESET

SYSTEM$("MSI")

WILDCARDS

File Types

BDAT Files

ASCII Files

Ordinary Files

File Organization

Sequential Files

Random Access Files

Converting LIF ASCII files to DOS ASCII


Chapter 10 CON
Contents

Chapter 10, IEEE-488 Interface Bus

Chapter 10	IEEE-488 Interface Bus

IEEE-488 History

IEEE-488 Overview

Data Lines

Handshake Lines

Interface Management Lines

Device Addresses

IEEE-488 Statement Overview

High Level Transfer Statements

High Level Bus Control Statements

ABORT Statement

CLEAR Statement

LOCAL Statement

LOCAL LOCKOUT Statement

PASS CONTROL Statement

PPOLL Function

PPOLL CONFIGURE Statement

PPOLL RESPONSE Statement

PPOLL UNCONFIGURE Statement

REMOTE Statement

REQUEST Statement

RESET Statement

SPOLL Function

TRIGGER Statement

Byte Level Transfer Statements

SEND Statement

OUTPUT and ENTER Statements

Low Level Bus Control Statements

CONTROL and STATUS Statements

READIO and WRITEIO Statements

IEEE-488 Interrupts

ON INTR Statement

OFF INTR Statement

Enabling and Disabling Interrupts

Interrupt Enable Register Bit Mask.

Handling Service Requests

Parallel Polling Devices

IEEE-488 Registers

IEEE-488 CONTROL Registers

CONTROL 0

CONTROL 1

CONTROL 2

CONTROL 3

CONTROL 4

CONTROL 5

IEEE-488 STATUS Registers

STATUS 0

STATUS 1

STATUS 2

STATUS 3

STATUS 4

STATUS 5

STATUS 6

STATUS 7

9914 READIO Registers

9914 READIO 1

9914 READIO 3

9914 READIO 5

9914 READIO 17

9914 READIO 19

9914 READIO 21

9914 READIO 23

9914 READIO 29

9914 READIO 31

9914 WRITEIO Registers

9914 WRITEIO 3

9914 WRITEIO 17

9914 WRITEIO 19

9914 WRITEIO 23

9914 WRITEIO 25

9914 WRITEIO 27

9914 WRITEIO 29

9914 WRITEIO 31

7210 READIO Registers

7210 READIO 1

7210 READIO 3

7210 READIO 5

7210 READIO 18

7210 READIO 20

7210 READIO 22

7210 READIO 24

7210 READIO 26

7210 READIO 28

7210 READIO 30

7210 READIO 32

7210 WRITEIO Registers

7210 WRITEIO 3

7210 WRITEIO 18

7210 WRITEIO 20

7210 WRITEIO 22

7210 WRITEIO 24

7210 WRITEIO 26

7210 WRITEIO 28

7210 WRITEIO 30

7210 WRITEIO 32

Statement Bus Action Summary

ABORT

CLEAR

LOCAL

LOCAL LOCKOUT

PASS CONTROL

PPOLL

PPOLL CONFIGURE

PPOLL UNCONFIGURE

REMOTE

SPOLL

TRIGGER


Chapter 11 CON
Contents

Chapter 11, Serial (RS-232) I/O

Chapter 11	Serial (RS-232) I/O

General I/O

Handshaking

ENTER Serial

OUTPUT Serial

Interrupt Support

Connecting Devices to the Serial Interface

"Standard" Cables

Cabling From the Ground Up

Communication Parameters

Data Formats

Interface Status Errors

RS-232: The Standard Non-Standard

The Standard

Pin Assignments for PC 25 and 9 pin connectors

The Non-Standard

Pin Assignments

Serial Registers

Serial CONTROL Registers

CONTROL 0

CONTROL 1

CONTROL 2

CONTROL 3

CONTROL 4

CONTROL 5

CONTROL 6

CONTROL 7

CONTROL 8 to 11

CONTROL 12

CONTROL 13

CONTROL 14

CONTROL 100

Serial STATUS Registers

STATUS 0

STATUS 1

STATUS 2

STATUS 3

STATUS 4

STATUS 5

STATUS 6

STATUS 7

STATUS 8

STATUS 9

STATUS 10

STATUS 11

STATUS 12

STATUS 13

STATUS 14

STATUS 100

STATUS 101

Serial READIO Registers

READIO 0

READIO 1

READIO 2

READIO 3

READIO 4

READIO 5

READIO 6

Serial WRITEIO Registers

Serial ENABLE INTR Mask


Chapter 12 CON
Contents

Chapter 12, Other I/O Destinations/Sources

Chapter 12	Other I/O Destinations/Sources

I/O to Strings

OUTPUT to Strings

ENTER from Strings

Buffers

BUFFER STATUS/CONTROL Registers

Pipes

The Processor Interface (32)

STATUS 0

STATUS 1

STATUS 2

STATUS 3

STATUS 4

Accessing Other Interfaces and Devices

Under DOS

DOS IN, OUT, PEEK, and POKE operations

DOS OBJ or Library Calls

DOS Device Driver

Under UNIX

Use Pipes


Chapter 13 CON
Contents

Chapter 13, International Language Support

Chapter 13	International Language Support

DOS Code Pages

Windows and Unix Character Sets

Character Sets

Code Pages 437 and 850

Roman-8

Latin-1

ISO-932 and Shift-JIS

Variable Names

Attribute Character Conflict

Lexical Order

Upper and Lowercase Conversions

Japanese Character Conversions

LABEL Character Set

Defining Your Own LABEL Characters

Using LABELCHR.BAS

Installing DOS Code Page Support

COUNTRY

DEVICE

GRAFTABL

NLSFUNC

MODE

KEYB

CHCP

Examples

User-Defined Lexical Orders

Order Table

Special Case Table

Ignore Characters

2-to-1 Translation

1-to-2 Translation

Sub-Order Numbers

Putting User-Defined Rules Into Effect

User-Defined UPC$/LWC$ Rules

Example Data Files

Roman-8 Character Set Support

Roman-8 Translation Program

DOS Display Font

Windows Display Font

Keyboard

LEXICAL ORDER

LABEL

LEXICAL ORDER Tables

Character Set Tables

Code Page 437 Character Set

Code Page 850 Character Set

LEXICAL ORDER IS FRENCH    (Code Page 850)

LEXICAL ORDER IS GERMAN   (Code Page 850)

LEXICAL ORDER IS SPANISH   (Code Page 850)

LEXICAL ORDER IS SWEDISH  (Code Page 850)

Roman-8 Character Set

LEXICAL ORDER IS FRENCH (Roman-8)

LEXICAL ORDER IS GERMAN (Roman-8)

LEXICAL ORDER IS SPANISH (Roman-8)

LEXICAL ORDER IS SWEDISH (Roman-8)

Latin-1 Character Set

LEXICAL ORDER IS FRENCH (Latin-1)

LEXICAL ORDER IS GERMAN (Latin-1)

LEXICAL ORDER IS SPANISH (Latin-1)

LEXICAL ORDER IS SWEDISH (Latin-1)

ISO-932 Character Set

Overview of the Shift-JIS Character Set


Chapter 1
Getting Started

This chapter convers two areas. First is a brief introduction to the manual layout. Then the integrated environment and common commands and statements used to develope programs using HTBasic are covered. After installing HTBasic read the chapters of the manual that are pertinent to your situation. Not every chapter is applicable to every version of HTBasic. Features that are specific to certain versions are noted.


High Tech Basic

High Tech Basic (HTBasic) is a technical programming language compatible with Hewlett Packard's "Rocky Mountain" BASIC for HP 9000 Series 200/300 computers. It has extensive graphics, instrument control capabilities, and interactive programming aids to speed program development. It is designed to offer powerful features and ease of use to engineers, scientists, and other professionals having a range of programming experience from novice to expert.

Note: The following terms are used in the following way in the HTBasic manuals: Rocky Mountain BASIC (RMB) is a dialect of BASIC. HTBasic and HP BASIC are particular implementations of RMB.

The HTBasic manual set consists of the Installing and Using manual, the User's Guide, the Reference Manual. Besides these three manuals, other manuals are available that describe special options to HTBasic, such as data acquisition, compiler, and math library.


Installation Manual

The Installing and Using manual should be read first. It explains how to install HTBasic and get it up and running. It presents the following topics:

•  Installing HTBasic
•  Keyboard Key Assignments
•  CRT and Graphic (Plotter) Drivers
•  Printer and Image File Drivers
•  Graphic Input Drivers
•  Serial and IEEE-488 (GPIB or HP-IB) drivers
•  Transferring Programs and Data From HP BASIC
•  Customizing the Environment
•  Solutions to Common Problems
•  Changes From Earlier Releases

HTBasic is highly configurable. Before it can be used, the necessary drivers must be loaded. A chapter also talks about softkey macros and creating HP workstation compatible BDAT files. It explains controlling implicit variable and string dimensioning and customizing keyboard key assignments. Defining additional LABEL characters is explained as well as specifying a path specifier to use for an HP disk drive. The chapter describes changing the value of PRT and creating program files that are compatible with standard program editors.

A different Installing and Using manual is provided for different versions of HTBasic. For example, Installing and Using HTBasic on the DOS Version covers installation for the DOS Version.


Reference Manual

The Reference Manual consists mainly of a dictionary style presentation of HTBasic keywords. The Reference Manual also is available from within HTBasic through the HELP statement. The manual includes a chapter of definitions, a statement summary table, a list of error messages, and an ASCII code chart. The ASCII code chart contains ASCII, decimal, and hexadecimal values and IEEE-488 commands and addresses.


This Manual

This manual, the User's Guide, contains in depth information about using the HTBasic language. It is arranged topically. The following list explains what each chapter of the manual describes and who should read it. After installing HTBasic read the chapters of the manual that are pertinent to your situation. Not every chapter is applicable to every version of HTBasic. Features that are specific to certain versions are noted.

Chapter 1, "Getting Started," covers two areas. The first area is a brief introduction to the manual layout. The second area describes the integrated environment and common commands and statements used to develop programs using HTBasic. RMB is more than a language, it is an entire environment. The display organization of RMB is different than other languages and dozens of special function keys are defined. It is important that all users read this chapter.

Chapter 2, "Porting HP BASIC Programs to HTBasic," is a porting guide for users with HP BASIC programs. It presents, statement by statement, differences between HTBasic and HP BASIC/WS. Users porting programs should read this chapter.


Language Definition

Chapters 3 to 6 explain the Rocky Mountain BASIC language. These chapters should be read by new users, or old users who need a review of RMB.

Chapter 3, "Language Elements," explains the basic elements of the language like keywords, operators, and variables.

Chapter 4, "Program Flow Control," explains how the path of program execution can be controlled to perform calls, loops, and decisions.

Chapter 5, "Mathematics," describes numeric expressions, string expressions, and array expressions. The various operators and functions are presented.

Chapter 6, "Graphics," presents the graphic drawing and presentation capabilities of HTBasic.


Input and Output

Chapter 7, "General Input and Output," explains Input and Output (I/O) in general. This chapter also explains the TRANSFER statement. The information in this chapter is necessary to understand chapters 8 to 12 and should be read by all users. Chapters 8 to 12 describe particular interfaces. You only need to read the chapters that describe interfaces that you will be using.

Chapter 8, "CRT, Keyboard, and Printer," describes I/O to the screen (CRT) and keyboard (KBD). In addition to the general I/O statements presented in chapter 7, RMB contains several statements specially designed for I/O to the screen or keyboard. Several statements are also presented that are designed for I/O with either the screen or a printer. All users should read this chapter. If you are using a printer, you should also read one of the following chapters that explains how to use the interface that your printer is connected to.

Chapter 9, "Files," presents I/O to files and the special file management statements available. These special statements often make it unnecessary to use operating system commands to move, copy, delete, or otherwise manipulate files.

Chapter 10, "IEEE-488 Interface Bus," explains use of the IEEE-488 (GPIB or HP-IB) interface.

Chapter 11, "Serial (RS-232) I/O," describes use of the Serial (RS-232) interface.

Chapter 12, "Other I/O Destinations," talks about I/O with a variety of I/O targets: Parallel (Centronix Printer) Interfaces, buffers, Strings, a special interface called the "Processor Interface," and pipes. This chapter also describes methods for using interfaces and devices for which there is no HTBasic device driver.


Advanced Topics

Chapter 13, "International Language Support," explains the support included in HTBasic for different languages and character sets. Users outside the United States and Canada should read this chapter. If you wish to use the HP Roman-8 character set used by HP BASIC rather than your computer's character set, you should read this chapter.

Chapter 14, "Mixed Language Programming," describes how to call subroutines written in other languages. This material is specific to the DOS Version of HTBasic.


Using the Integrated Environment

The HTBasic integrated programming environment is made up of the display, keyboard, function keys, mouse, program development commands, program file management commands, softkey macros, and the CONFIGURE statement. Each of these elements work together to produce a powerful program development and execution environment that includes live keyboard command and statement execution, a full screen syntax sensitive editor, and an on-line HELP system.


Display Screen

The HTBasic display operates in one of three modes, Normal, Edit, and Help. The Normal display mode is used while HTBasic is idle, waiting for a command, or while a program is running. The EDIT display mode is used by the full screen editor to display and modify programs. The Help display mode is used by the on-line Help system. The following diagram shows the organization of the HTBasic display in normal mode.


Output Area

The Output Area is where program output is displayed (by default) from a variety of statements, including PRINT, OUTPUT CRT, LIST, CAT, etc. This area starts at the top line of the screen and extends down to one line above the DISP line. The Output Area is the visible part of an Extended Output Area. This Extended Output Area allows lines of the Output Area to be saved as they are scrolled off the top or bottom of the visible screen area. The UP, DOWN, NEXT, and PREV, function keys scroll the Extended Output Area up and down, allowing all parts of it to be viewed. The CLR SCR function key clears the entire Extended Output Area.

Note: HTBasic function keys have generic names that generally match the key names on an HP BASIC Workstation. The actual key assignments for your keyboard are given in the Installing and Using manual.

The Output Area displays characters at the current print location. If the print location has been scrolled out of the visible screen area, the Output Area is first scrolled so that the print location is visible and then the new characters are displayed and the print location is updated. The print location may be set by the CONTROL CRT,0;c,r statement. Five character values perform special control actions in the Output Area. They are:


Control Characters

Character	Function
CHR$(7)	Ring the Bell.
CHR$(8)	Move the print location back one space.
CHR$(10)	Move the print location down one line.
CHR$(12)	Print two line feeds, scroll the Output Area so
that the next line is at the top of the Output Area.
CHR$(13)	Move the print location to column one.

The actions of these control characters can be disabled and all character values between CHR$(0) and CHR$(255) displayed with the DISPLAY ALL function. This can be toggled on and off by the DISPLAY FCTNS key or controlled by the CONTROL CRT,4 statement.


Display Enhancements Characters

Additional character values control display enhancements. These characters are:

Character	Function
CHR$(128)	All enhancements off.
CHR$(129)	Inverse video on.
CHR$(130)	Blinking video on.
CHR$(131)	Inverse and Blinking video on.
CHR$(132)	Underline mode on.
CHR$(133)	Underline and Inverse video on.
CHR$(134)	Underline and Blinking video on.
CHR$(135)	Underline, Inverse, and Blinking video on.

Character	Function
CHR$(136)	White
CHR$(137)	Red
CHR$(138)	Yellow
CHR$(139)	Green
CHR$(140)	Cyan
CHR$(141)	Blue
CHR$(142)	Magenta
CHR$(143)	Black

Because some computers, including the IBM PC, use character sets with character values that conflict with these characters, the CONTROL CRT,100 statement allows these display enhancement control characters to be moved to the range CHR$(16) through CHR$(31).


Display Line

The Display Line is used for displaying prompts for the INPUT and the LINPUT statements and for displaying text with the DISP statement. The Display line maintains a current print location and if it moves past the right-most column, the display line scrolls to the left so that the last character is displayed. The print location may be set by the CONTROL CRT,8 statement. The same control and enhancement characters are active for the Display Line as for the Output Area with the following differences:

Character	Function
CHR$(12)	Clears the DISP line.
CHR$(13)	Moves the DISP line cursor to column one, and clears
the DISP line when the next character is sent to the
DISP line.

The DISPLAY ALL function has no effect on the Display Line and other control characters are not stored in the Display Line buffer. The Display Line buffer content may be read by a program using SYSTEM$("DISP LINE").


Input Line

The Input Line is used to enter commands, program lines, calculator expressions, and other keyboard input. Any of the line editing keys, discussed later in this chapter, may be used to modify this area. When ENTER is pressed the Input Line buffer is sent to either the INPUT, LINPUT, ENTER KBD statement or to the command and statement parser. At any time while either a program is running or HTBasic is idle, you may enter commands or expressions for immediate execution. This Live Keyboard execution feature is described in detail later in this chapter.


Message Line

The Message Line displays error messages, live keyboard calculator results, and status indicators. The status indicators display the current softkey menu and the current state of HTBasic. The current state indicates whether the user program is running, paused, stopped, or waiting for input. It also indicates when you are in the HELP or EDIT modes. Messages longer than 63 characters are truncated to 63 characters.


Softkey Menu

The softkey menu displays labels corresponding to each softkey. The label indicates the action that is performed when the corresponding function key is pressed. There are several sets of softkeys that can be displayed including the system softkeys and three sets of user softkeys. There are two softkey layouts available that correspond to either the HP Nimitz or ITF keyboards. These were explained in the Installing and Using manual.


Customizing the Environment

HTBasic provides a keyboard function key macro facility and a CONFIGURE statement that can both be used to customize the programming and execution environment. Each of these features is discussed in the Installing and Using manual.


Program Development

Program development under the HTBasic integrated environment is made easy by program documentation statements, live keyboard execution, and Edit mode with its related commands. After each of these elements of program development is discussed, alternate editing techniques and the statements and commands used to run, debug, save, load, and manage program files are presented.


Program Documentation

Program documentation is important because it clarifies and explains the structure and function of a program. Almost everyone that has ever written a program has wished to change or modify that program or a program written by someone else at a later date. If its structure and function have been well documented, that task is relatively simple and straight forward. If not, it can be a long and difficult task.

In HTBasic, there are several ways to document a program: with the REM (remark) statement, comment tails "!", and with mnemonic variable names and program line labels.

The REM and "!" statements are used to insert comments into programs. A "!" comment may be appended to the end of any program statement. They may contain any text you wish, are useful in explaining what the program is doing, and are ignored when the line is executed. When an INDENT command is given, the position of a REM statement is changed to match the current indentation level but the position of a "!" comment is left unchanged.

Line labels may be used in program statements in the place of line number references. The label name is independent of the line number and can be much more meaningful than a line number. It is more convenient to enter "EDIT Open_valve", for example, than to look up the currently assigned line number and enter "EDIT nnnn".


Live Keyboard Execution

At most any time you can enter from the keyboard a command, a list of expressions, or a program line that starts with a line number. Commands are executed, expressions are evaluated and their results displayed in the message line, and program lines are checked for correct syntax and stored into program memory. If results displayed on the message line are longer than 63 characters, the results are truncated to 63 characters. If a syntax error is detected in a program line, an error message is displayed in the system message line and the cursor is positioned over the error. You can use the HELP command to display the Reference Manual entry for the statement to determine how to correct the syntax error. For example:

INDENT           ! command
PI*2             ! expression
100 FOR J=1 TO 5 ! program line

Any statement you enter without a line number will be executed as an immediate command. Some commands, however, might have more than one meaning depending on how they are entered. For example, you can enter X<4 from the keyboard and HTBasic will display a 1 or 0 depending on its logical value. Suppose, however, that you enter X=4. This looks more like an assignment than a logical comparison, and this is just how HTBasic will treat it. If it was your objective to test whether X was equal to 4, you could do this by entering it in parenthesis: (X=4). In this case, HTBasic will display a 1 or 0 depending on the value of X.


HELP Command

The HELP command is used to look up material in a disk-based Reference Manual. This disk-based manual is virtually the same as the printed Reference Manual. The manual is arranged alphabetically. To look up a keyword in the manual, when not in the HELP mode, type "HELP" followed by the keyword. For example, to look up the keyword GOTO you would type:

HELP GOTO

and press ENTER. The first page about that keyword will be displayed. You may then read forward in the manual. If you are already in HELP mode, don't type the leading "HELP."

Standard Windows HELP file commands work for the Windows Version. For DOS and UNIX versions, to switch to a different keyword while in the HELP mode, type the new keyword and press ENTER. To get another page of information, press ENTER. To exit the HELP mode, press CLR SCR. To read something that has recently scrolled off the top of the screen, scroll the screen back using PREV and NEXT or the UP and DOWN arrow keys.

Some statements include a secondary keyword. For example, the keyword ON can be followed by secondary keywords such as CYCLE, DELAY, etc. To go directly to this kind of manual entry, include both keywords. For example:

HELP ON DELAY

To read the introduction at the start of the disk-based Reference Manual, give the command "HELP" with no keyword. The introduction contains a Syntax Definition Conventions chapter where conventions used throughout the manuals are explained and a Definitions chapter where general HTBasic terms and syntactical units are defined.


EDIT Mode

The easiest way to develop an HTBasic program is with the built in full screen syntax-sensitive editor. The EDIT command puts you into Edit mode and gives you full screen program editing capability. Line numbers are generated and maintained automatically. Program lines can be changed, inserted, deleted, indented, and automatically or manually renumbered. You can do global FIND and CHANGE operations. You can MOVELINES or COPYLINES with automatic program line reference renumbering. This diagram shows the organization of the display in EDIT mode.

While in Edit mode, a full screen of program lines is displayed. The Message Line displays the error messages, live keyboard calculator results, and status indicators. The softkey menu displays softkey labels corresponding to the function keys, the same as when the display is in normal mode.

Program lines up to the Rocky Mountain Basic limit of 255 characters can be edited, regardless of the screen width. Furthermore, if your screen or window size is wider than 80 characters, the full screen width is utilized. Lines longer than the screen width are scrolled as necessary to allow editing of any part of the line.

You may move the cursor up and down through the displayed program lines with the UP and DOWN keys and you may scroll through the program with the UP, DOWN, PREV, NEXT, BEGIN, and END keys. You may change any displayed program line with any of the line editing function keys previously discussed. Upon entry, each program line is syntax checked and immediate error feedback is provided.


SUB Mode

With the EDIT SUB Mode, the HTBasic editor allows quick navigation of subprograms (SUB, DEF FN, CSUB). Press the SUB Mode key once to display and move through the subprogram list; press it again to switch back to regular editing mode.


Save Changes

The editor keeps track of program changes and asks for confirmation before discarding them. For example, if you make some changes to your program, then get distracted, and then attempt to QUIT HTBasic, you will be alerted to the fact that the changes have not been saved yet. You then have an opportunity to save the changes or discard them.


Starting Edit Mode

Edit mode is started by pressing the EDIT key (or typing EDIT), optionally giving a line number and subprogram name, and then pressing ENTER. When editing an existing program, the current edit line will be set either to the last line edited, the last line with an error, or the line specified in the EDIT command. For example:

EDIT 100

starts the editor with line number 100 as the current edit line. You may specify either a line number, line label, SUB program name or DEF FN function name. For example to edit the SUB program TEST enter:

EDIT SUB Test

To edit the function Pete enter:

EDIT FNPete

The default increment for new line numbers automatically produced by the editor is ten, but may be specified with an optional increment as follows:

EDIT 100,5


Terminating Edit Mode

EDIT mode is ended by pressing the CLR SCR, PAUSE, RUN, or STEP keys. It can also be terminated by entering a CAT or LIST command without a line number.


Controlling the Cursor

While in EDIT mode, the UP, DOWN, LEFT, and RIGHT arrow keys, NEXT WORD, LEFT WORD, PREV, NEXT, BOL, EOL, BEGIN, and END keys are used to move around the program. The INS CHR key toggles the overstrike mode to insert mode and back again. The mode remains in effect until the INS CHR key is pressed again. The DEL CHR key deletes the character under the cursor. The DEL LEFT key deletes the character left of the cursor.


Syntax Checking

No changes are made to the stored program until you press the ENTER key. The edit line is then checked for correct syntax and if there are no errors it is stored into memory. If a syntax error is detected, an error message is displayed on the message line and the cursor is positioned at the error. If you wish to abort the changes, press any key that moves to another program line.


Inserting Lines

To insert a new program line between two existing program lines, or before the first line of the program, position the cursor on the following line and then press INS LN. If necessary, the program will be partially renumbered, and a new line number will be generated for you. After a line has been entered, a new line number is generated and displayed ready for you to enter the next program line. To exit insert line mode press the UP, DOWN, PREV, NEXT, BEGIN, END, INS LN, or DEL LN keys.


Deleting Lines

To delete a program line, position the cursor on the line you wish to delete, and press DEL LN. A line that has been accidentally deleted can be recovered by pressing the RECALL key followed by the ENTER key.


Immediate Commands

Immediate commands can be entered in EDIT mode by first deleting the automatic line number and then entering the command. To delete the line number, backspace over it, and then type over the top of it, or use CLR LN (not DEL LN) to clear the current line.


Associated Commands

The following program development commands are used in conjunction with the EDIT command.

•  FIND - search for a string of characters
•  CHANGE - finds a string and replaces it with another string
•  INDENT - indents structured program constructs
•  REN - renumbers program sections
•  DEL - removes program lines
•  SCRATCH - removes all program lines or COM blocks from memory
•  XREF - generates a program cross-reference listing
•  COPYLINES - copies a program section to another place
•  MOVELINES - moves a program section to another place
•  SECURE - makes a program section not listable

Each of these commands is discussed on the following pages.


FIND Command

The FIND command searches for a specified character sequence in a program. The program string must exactly match the string specified in the FIND command. The case of the characters in the search string is significant.

Once found, the program line may be modified or deleted. The search continues after pressing the ENTER or DEL LN keys. If no modification or deletion is needed, pressing CONTINUE searches for the next occurrence. You exit FIND mode by pressing any other function key. For example:

FIND "Xx="

will search for the first program line that contains an upper case X followed by a lower case x and an equals sign. If a line is found that contains this string it is made the current edit line. If not already in EDIT mode, edit mode is entered and the edit screen is displayed.

If an optional starting line is specified, the search begins with that line. If that line doesn't exist, the line immediately after that line number is used. If a non-existent line label is specified, an error is reported. If the start line is not specified, the search begins with the current line if you are already in EDIT mode or the first program line if not in EDIT mode.

If an optional end line is specified, the search ends with that line. If that line doesn't exist, the line immediately before that line number is used. If a non-existent line label is specified, an error is reported. If the end line is not specified, the search ends with the last program line. For example:

FIND "Xx=" IN 1500,2500

will start the search with line number 1500 and end the search with line number 2500. The first line found that includes the string "Xx=" becomes the current edit line.

FIND is not allowed while a program is running, but may be used when the program is paused. FIND is aborted if a line number is altered.


CHANGE Command

The CHANGE command allows you to search and replace character sequences. The old and new strings are used exactly as given with the case being significant. For example:

CHANGE "quoted" TO "QUOTED"

will change the lowercase string "quoted" to the uppercase string "QUOTED". The computer searches for each occurrence, displays the line with the change, and then asks you if you want this replacement. If you do, press the ENTER key; if you don't, press the CONTINUE key. If you wish to abort the CHANGE command, press any other function key. When no further occurrences of the search string can be found, the "<old-string> not found" message is displayed.

If the optional ALL keyword is included, all of the changes are made automatically without any user interaction. For example:

CHANGE "old" TO "new";ALL

replaces all occurrences of "old" in the program with "new". If not already in EDIT mode, edit mode is entered and the edit screen is displayed. Optional starting and ending line numbers or line labels may be specified as described for the FIND statement. For Example:

CHANGE "Apples" TO "Oranges" IN 1200,1500

limits the search range to the lines numbered 1200 through 1500.

The CHANGE command is not allowed while a program is running, but may be used while a program is paused. An error message will be displayed if a syntax error occurs during any CHANGE operation. After the line is corrected the CHANGE command continues. The CHANGE operation is aborted if a change exceeds the maximum allowable length of a program line, or if a line number is altered.


COPYLINES Command

The COPYLINES command copies one or more program lines from one location to another while leaving the original lines in place. This differs from the MOVELINES command that deletes the original program lines. For example:

COPYLINES 10,100 TO 500

copies the program lines between line number 10 and 100 to the new starting line number 500. Appropriate renumbering occurs to insert the new program lines into the existing program. If no ending line is specified, only one line is copied. For example:

COPYLINES 1500 TO 2220

The target line cannot be in the range specified by the start and the end line numbers or labels. If the start line doesn't exist, the line immediately after that line number is used. If the end line doesn't exist, the line immediately before that line number is used. If a non-existent line label is specified, an error is reported. If the arguments specify a destination line number or program section that already exists, the old section is renumbered to make room for the new program lines.

Line numbers are renumbered and updated if needed. Line number references in lines not being copied remain linked to the original lines rather than the newly created lines. If an error occurs during a COPYLINES, the copy is terminated and the program is left partially changed.

COPYLINES may not copy lines containing a SUB or DEF FN statement unless the new line number is larger than any existing line number.


MOVELINES Command

The MOVELINES command moves one or more program lines from one location to another. This differs from the COPYLINES command that leaves the original lines in place. For example:

MOVELINES 500,1200 TO 4100

moves the program lines with line numbers 500 through 1200 to the new starting line number 4100. Appropriate renumbering occurs to insert the new program lines into the existing program. If no ending line is specified, only one line is moved. For example:

MOVELINES 600 TO 1500

The target line cannot be in the range specified by the start and the end line numbers. If the start line does not exist, the line immediately after that line number is used. If the end line does not exist, the line immediately before that line number is used. If a non-existent line label is specified, an error is reported. If the arguments specify a destination line number or program section that already exists, the old section is renumbered to make room for the new program lines.

Line numbers are renumbered and updated if needed. If an error occurs during a MOVELINES, the move is terminated and the program is left partially changed.

MOVELINES may not move lines containing a SUB or DEF FN statement unless the new line number is larger than any existing line number.


INDENT Command

The INDENT command inserts spaces after the line numbers and before the leading keywords of all lines in a program to visually show the structure of the program. It does not move "!" comment statements. This command can only be executed from the keyboard. It cannot be included in a program.

The following statements add a level of indentation: DEF FN, FOR, IF...THEN, LOOP, REPEAT, SELECT, SUB, and WHILE. The following statements are printed one indentation level to the left, but leave the indentation level unchanged: CASE, CASE ELSE, ELSE, EXIT IF, FNEND, and SUBEND. The following statements subtract one level of indentation: END IF, END LOOP, END SELECT, END WHILE, NEXT, and UNTIL.

The optional increment value specifies how many spaces to indent each successive structure level. The default increment value is two. The optional start-column specifies the column in which to start non-indented program lines. The default start-column is six. For example:

INDENT 10,5

indents all program statements to column ten and each structure level an additional five spaces.


REN Command

The REN command  renumbers program lines, including the line references in all program statements such as GOSUB and GOTO to match the new line numbers. This command can only be executed from the keyboard. It cannot be included in a program.

You can optionally specify the new starting line number, the increment between lines, and a range of lines to renumber. If you renumber a paused program, it changes to the stopped state. For example:

REN 1000,5 IN 100,800

renumbers the program lines between 100 and 800 to start at line number 1000 with an increment of five. If not specified, the default value for both the new starting line number and the increment is ten.

You cannot specify a new starting line number that would cause the lines to change position in the program with respect to other existing program lines. Use the COPYLINES or the MOVELINES commands, described earlier in this chapter, to do this.


DEL Command

The DEL command removes program lines from memory. A range of program lines can be deleted by separating the starting and ending line numbers or line labels with a comma. For example:

DEL Start,1500

removes all the program lines between the line labeled "Start" and the line numbered 1500 from memory. If only one line is specified, only that line is deleted. Once a DEL statement has been executed, the specified lines cannot be retrieved.

DEL cannot be executed from a running program, but can be executed while the program is paused. After the DEL command is executed the program is changed to the stopped state. SUB and DEF statements can not be deleted unless the entire subprogram is included in the range.


SCRATCH Command

The SCRATCH command allows you to clear the BASIC program, variables, and COM variables from memory.

SCRATCH

deletes the current BASIC program, and any variables not in COM statements.

SCRATCH ALL

(or SCRATCH A) clears the BASIC program, all variables, including those in COM, and all softkey macro definitions. Internal parameters are set to their default, start-up values.

SCRATCH COM

(or SCRATCH C) clears all variables including those in COM, but leaves the BASIC program and the softkey macro definitions intact.


XREF Command

The XREF command generates a cross-reference listing of line numbers and labels, I/O-path variables, numeric and string variables, subprograms, functions, and COM blocks. It also lists the number of unused symbol table entries currently in each context. The listing is sent to the PRINTER IS device unless a device selector is specified.

If you specify no options, all contexts and all data types will be cross-referenced. For example:

XREF #10

will cross-reference all program contexts and send the listing to interface select code ten. You may specify that only the "Main" context or a specific subprogram context be cross-referenced. You may further specify that only one of the data type options be cross-referenced. For example:

XREF Trigger:NV

will cross-reference the subprogram context "Trigger" and generate a cross-reference listing of just the Numeric Variables (NV). Whereas:

XREF Main

will cross-reference the Main program context and generate a cross-reference listing of all the data types. The data type specifier options follow a colon and are:

Option	Meaning
CM	Common Block Names
IO	I/O Path Variables
LL	Line Labels
LN	Line Numbers
NF	Numeric Function Subprograms
NV	Numeric Variables
SB	SUB Subprograms
SF	String Function Subprograms
SV	String Variables
UN	Unused Entries

Each data type in the context will be cross-referenced and output as a group. If no references of that type appear in the context the data type heading will not be generated. A reference to a SUB parameter, a variable declared in a COM, DIM, REAL, COMPLEX, or INTEGER statement, or a line label, is marked with "<-DEF" in the cross-reference listing.


SECURE Command

The SECURE command protects programs lines so they cannot be listed. Secured lines are listed as a line number followed by an asterisk "*" character. Once a program line has been secured it can never again be listed. To secure all program lines, use the following:

SECURE

An optional line range may be specified. For Example:

SECURE Payrolla,Payrollb

secures all the program lines between line label "Payrolla" and "Payrollb". If no end-line is specified, only the start-line is secured.

Note: Please be sure that you have a backup copy of your program before using the SECURE command. Do not inadvertently overwrite your original non-secured program with the RE-STORE command!


Alternate Editing Techniques

There are several other ways to develop an HTBasic program. You can enter each program line one at a time into the input line and display your program with the LIST statement. With this method, you must maintain a picture of the program in your mind as you make changes and completely re-enter each line that you wish to modify.

The LIST statement outputs the program in memory to the PRINTER IS device, normally the CRT. After the program is listed, the available memory size in bytes is displayed on the system message line. For example:

LIST 1500,1725

outputs the program lines numbered from 1500 through 1725 to the PRINTER IS device. If a device selector is given the output is directed to that device. For example:

LIST #702

lists all contexts and directs the output to an IEEE-488 printer at address 2.


Using an Editor

Another way to develop HTBasic programs is to use your favorite editor. A word processor can also be used if it has a method of reading in and saving out ASCII files. Execute the HTBasic statement CONFIGURE SAVE ASCII OFF to instruct HTBasic not to use LIF ASCII format for the SAVE statement. SAVE will then produce ordinary ASCII files. It may be convenient to place this statement in your AUTOST file.

If using a word processor, save the program in ASCII format rather than the word processor's usual format. Enter it into HTBasic with the GET command. The syntax of each program line is checked as the program is loaded. If a syntax error is found, the line is listed to the current PRINTER IS device, turned into a comment by adding "!* " after the line number, and saved in memory with the other program lines for later correction. If you make changes to the program with the HTBasic editor, remember to RE-SAVE it or re-make the changes using your editor.


Running and Stopping Programs

The RUN command or the RUN function key starts program execution. It is executed in two parts, prerun initialization and program execution.

Prerun initialization reserves memory space for variables declared in DIM, COMPLEX, REAL, INTEGER, COM statements, and variables implied in the program. Numeric variables are set to zero and string variables are set to zero length. Prerun also checks for multi-line errors such as illegal program structure, array references, and mismatched COM blocks. Each COM block in the program is compared to the old COM blocks in memory. Any mismatched COM blocks are deleted.

Prerun errors are reported to the user and the program halts. Some types of prerun errors generate several error message lines, although only the last remains visible on the message line. To see all the error message lines, turn PRINTALL on. If prerun detects no errors, the main program is started at the beginning, or at an optional program line or label, if specified. The program runs normally until it encounters a PAUSE, STOP, or END statement, a TRACE PAUSE line, or an error.


STOP

The STOP statement or function key terminates program execution. When the program stops execution, I/O paths not in COM are closed, and all variables are discarded. The CONT command cannot be used after a STOP. To restart program execution you must use the RUN statement.


QUIT

The QUIT statement stops HTBasic and returns control to the operating system. It is used to leave the HTBasic programming environment. If used from the keyboard and the program is in a paused state or it is included in a program, a STOP is first executed to close any open files. It may be used in connection with operating system batch files to provide an enormous amount of flexibility in running combinations of HTBasic and other operating system programs. Please read your operating system manual for an explanation of batch or command files.


Debugging Programs

HTBasic includes many features for program debugging. The RESET, CLR I/O, PAUSE, CONT, STEP, and TRACE statements and function keys are discussed in the following sections.

You can stop a running program at any time by pressing the RESET key but this is rather drastic. It exits any subprogram contexts that may have been executing and returns you to the main context where you may examine any variables defined there. Pressing the CLR I/O key while in an I/O statement will also halt program execution.


Pausing the Program

A less drastic method of halting program execution is the PAUSE statement or the PAUSE key. When the PAUSE statement is executed or the PAUSE key is pressed the next program line is displayed in the system message area and the program is temporarily halted before the next line is executed. While the program is paused, you can examine and change the values of any variables in the current context and use any commands that do not change the program.


Continue

The CONT command or function key resumes program execution if the program is currently paused. If you specify an optional line number or line label, it must be in either the current context or the main context and execution continues at the specified line. If no line is specified, execution resumes at the next line that would have been executed had the program not been halted. If a change has been made to any program statement, the program is stopped and you cannot continue execution. RUN must then be used to restart program execution.


STEP

The STEP function key executes one line of the program, displays the next program line in the message area, and then pauses. If the program is not currently paused, the first press of this key causes the program to be prerun. If no prerun errors are detected the first program line is displayed in the message area. The next press of the STEP key executes the first program line, displays the next program line in the message area, and then pauses. The STEP function key steps into subprograms one line at a time.


TRACE Statement

The TRACE statement controls the display of trace information from a running program and can pause program execution before executing a specific program line. The trace output is sent to the system message line. The trace output is also sent to the PRINTALL IS device if PRINTALL is enabled. Tracing slows program execution.

TRACE ALL enables program tracing. Either the entire program or just a range of program lines may be traced. For example:

TRACE ALL 1000,1200

enables tracing during the execution of program lines 1000 through 1200. The trace output displays the program line before it is executed and any modified simple variables or array elements and their new values. If a full array is modified then only the array name is displayed. The TRACE OFF form turns off all tracing. For example:

TRACE OFF

disables all tracing. TRACE PAUSE will pause program execution before the specified program line is executed. If no line number or label is specified, the program pauses before the next program line is executed and the current TRACE PAUSE line is deactivated. For example:

TRACE PAUSE 250

will pause the program before line 250 is executed. By using these debugging aids you will be able to find errors in your programs quickly and efficiently, cut debugging time, and increase productivity.


Saving Programs

HTBasic has two statements for saving programs, SAVE and STORE. If the program has been saved before, RE-SAVE and RE-STORE are used to save the current version in place of the previous version in the same file.


STORE Statement

The STORE statement saves a program to a file in PROG format. PROG format is the incrementally compiled, internal binary format used by HTBasic to represent the program. PROG files load very quickly, and if stored after the prerun has been done on a program, start executing more quickly than ASCII files.

The STORE statement saves the entire program in memory including any subprograms to a new PROG file. The program is written to the specified file using the internal binary format. For example:

STORE "TEST"

creates a new PROG file named "TEST" and outputs the entire program in memory. If the specified file already exists, an error is reported. Use the RE-STORE statement to update an existing PROG file. For example:

RE-STORE "TEST"

uses the existing PROG file named "TEST" and outputs the entire program in memory. You can STORE a program after it has been prerun by first pressing the STEP key and then entering the STORE command. This stores the program in the prerun state and it will not have to be prerun when it is reloaded and executed. This is especially helpful for SUB subprograms that will be loaded and used from a running program.

Note: Because PROG files reflect the internal binary format of HTBasic, PROG files are not always transportable among versions of HTBasic. For example, the architecture of an IBM PC is sufficiently different from an HP 700 that PROG files are not compatible between the two. ASCII files remain the preferred file type for program exchange.


SAVE Statement

The SAVE statement saves a program to a file, either in LIF ASCII or ordinary ASCII format, depending on the setting of CONFIGURE SAVE ASCII. LIF ASCII is the default. If CONFIGURE SAVE ASCII OFF has been executed, the file type will be Ordinary ASCII.

If the specified file already exists, SAVE generates an error message; whereas RE-SAVE will reuse an existing file. RE-SAVE produces the same file type as an existing file, or the file type specified by CONFIGURE SAVE ASCII if no file exists.

SAVE "MYPROG"

creates a new ASCII file named "MYPROG" and outputs the entire program in memory. You may specify an optional program line range with two line numbers or line labels. This will output just the program lines within the specified range. For example:

SAVE "PENNIES",1000,3500

creates a new file named "PENNIES" and outputs only the program lines between line numbers 1000 and 3500.

ASCII programs load more slowly than PROG files and must be prerun before they are executed. Generally, PROG files are a better way to store programs, but ASCII files are useful in particular circumstances.

If you always store a program in PROG format, and if you periodically make changes to it, the symbol tables associated with the program's contexts may contain entries for variables that are no longer referenced. Using SAVE and then GET compresses the symbol table associated with the program's contexts. RE-STORE then stores the program in PROG format with the compressed symbol table.

ASCII files can also be used as an intermediate format when upgrading PROG files from a previous version of HTBasic or moving programs between versions of HTBasic with incompatible PROG formats.

LIF ASCII files can be exchanged with HP Workstations. Ordinary ASCII files can be edited with program editors and most word processors. Ordinary ASCII files can be exchanged with the HP BASIC Language processor card (Viper card) and recent releases of HP BASIC/WS.


Loading Programs

After you save a program, you can later re-load it into memory. This is done with the GET or LOAD statements. The GET statement is used to load programs stored in ASCII files with the SAVE statement. The LOAD statement is used to load programs stored in PROG files with the STORE statement.


GET Statement

The GET statement loads an ASCII program file into memory. You may specify an optional append line number or label and an optional starting line number.

GET "A:CODEFILE",2500  ! append line number
GET "GMAT",10,10       ! append & start line number

If the optional append line number or label is not specified the entire program and variables (except for COM variables) are first deleted and the new program lines are read into memory at their specified line numbers. If the optional  append line number is specified, the program lines in memory from that line number to the end of the program are deleted before any new lines are added to the program. Each new program line is renumbered to fit at the specified append location.

The first program line is read from the file and checked for a valid line number. If none is found, an error is reported. If a valid line number is found, the current program and variables are first deleted. Then each new program line is read and syntax checked. If a syntax error is found, the line is listed to the current PRINTER IS device, turned into a comment by adding "!* " after the line number, and saved in memory with the other program lines for later correction.

If GET specifies a run line (which must be in the main context), execution resumes automatically at the run line after a prerun. Each COM block in the new program is compared to the old COM blocks in memory. Any mismatched COM blocks are deleted. If GET, executed from a program, does not specify a run line, execution resumes at the beginning of the program. If GET, executed from the keyboard, does not specify a run line, a RUN command must be given to start execution. If a syntax error occurred during the GET, the error is reported and the program is not run.

The GET statement can read Ordinary ASCII (DOS ASCII or UNIX ASCII), LIF ASCII, Viper-I ASCII, and Viper-II ASCII files.


LOAD Statement

The LOAD statement loads a program from a PROG file into memory. The current program and all variables (except those in COM) are deleted. All contexts defined in the PROG file, including any subprograms, are loaded into memory. You may specify an optional starting line number in the main context. For example:

LOAD "Utility",200

If a run line is specified, execution resumes automatically at that line after a prerun. Each COM block in the new program is compared to the old COM blocks in memory. Any mismatched COM blocks are deleted. If LOAD, executed from a program, does not specify a run line, execution resumes at the beginning of the program after a prerun. If LOAD, executed from the keyboard, does not specify a run line, a RUN command must be given to start execution.


Subprograms

HTBasic implements true subprogram capability. Each subprogram makes up a context, is assigned its own local data allocated at each invocation, and may reference COM variables. If you have less memory space available than you need to implement a large program, you can often get around this problem by segmenting your program into several subprograms.

Subprograms are of two types: SUB and DEF FN. SUB subprograms are invoked with the CALL statement. DEF FN subprograms  (user defined functions) are invoked by referencing their name in an expression. They return either a numeric or a string result upon completion.

When you store the current program in memory to a PROG file, all the subprograms are stored along with the main context, if any. Subprograms may be manipulated individually with the LOADSUB and DELSUB statements.


LOADSUB Statement

The LOADSUB statement loads a subprogram from a PROG format file into memory at the end of the current program and renumbers the incoming subprogram lines. It also preruns the loaded subprograms to check the COM blocks. No new COM blocks may be specified in the subprogram.

There are three forms of the LOADSUB statement. The first two forms specify either a specific subprogram name or the ALL keyword and are programmable. If a subprogram name is specified, only that subprogram is loaded into memory. For example:

LOADSUB Peek FROM "TOOLS"

loads the subprogram named Peek from the PROG file named TOOLS. If the ALL keyword is specified, all subprograms defined in the file are loaded into memory. For example:

LOADSUB ALL FROM "UNITS"

loads all of the subprograms defined in the PROG file named "UNITS".

The LOADSUB FROM form loads all referenced subprograms not yet in memory from a specified file. The newly loaded subprograms are also examined and any additional subprogram references not yet in memory are also loaded. If any referenced subprograms were not found in the file, an error is generated along with a listing of the subprogram names. This form of LOADSUB is not programmable. For example:

LOADSUB FROM "UNITS"


DELSUB Statement

The DELSUB statement removes one or more subprograms from memory. For example:

DELSUB Unit1,FNOutput$,Stop_it

removes the three subprograms Unit1, FNOutput$, and Stop_it. If two subprograms have the same name, only the first one is deleted. You cannot delete a  subprogram if it is currently active or if it is referenced by an active ON-event statement.

If the TO END modifier is included, the subprogram plus all the following subprograms are deleted up to the end of the program. For example:

DELSUB Transform TO END

deletes the subprogram Transform and all subprograms through the end of the program.


Porting HP BASIC Programs to HTBasic
Chapter 2
Porting HP BASIC Programs to HTBasic

This chapter describes differences between HP BASIC and HTBasic. If you are transferring programs from HP 9000 Series 200/300 computers to HTBasic, you should read this entire chapter. Differences in hardware, file system, and keywords are discussed.

The CONFIGURE command allows you customize HTBasic to more nearly match the configuration of an HP Series 200/300 computer and is explained in Chapter 8 of the Installing and Using manual. Chapter 7 of the Installing and Using manual also explains methods for transferring programs and data from an existing HP BASIC Workstation.


Compatibility

HTBasic is compatible with Hewlett-Packard's 9000 Series 200/300 "Rocky Mountain" BASIC, and runs on a variety of hardware platforms — without the need for a coprocessor board. It includes most of the language features defined in the HP 6.2 LOADable BIN files.

HTBasic is not compatible with Series 80 or 9835/9845 BASIC. But there are translator programs available from third parties to translate from other BASICs to Rocky Mountain BASIC, and to transfer files among different systems.


Hardware Differences

HTBasic compensates automatically for many of the hardware differences that exist between an HP 9000 Series 200/300 workstation and other hardware platforms. The following sections outline many of the differences and explain what limitations still apply.


Disk Drives

HP-IB disk drives are not supported. No mass storage device is supported across the HP-IB. HP LIF disks are not compatible with DOS, NT and UNIX disk formats and cannot be read or written directly by DOS, NT, UNIX, or HTBasic. Check Chapter 7 of the Installing and Using manual for methods of transferring data and programs. On the PC, HPCOPY is used to transfer data and programs back and forth. Meadow Soft Works, mentioned earlier in this chapter, offers a DOS utility to transfer files from LIF hard disks hooked to the HP-IB.


Softkey Layout

Different keyboard layouts are used by PCs, Sun Workstations, and HP Workstations. Some keyboards have the softkeys down the left side of the keyboard, and some have them across the top of the keyboard. To make up for these differences and the lack of spatial coherence between the physical keys and the softkey menu, HTBasic menu labels have been numbered. This provides numerical coherence. The label numbered "1" always corresponds to the softkey with the "1" printed on it. The number is not meant to be the softkey number.

Note: to provide compatibility with programs written for the 9836 Nimitz keyboard (which starts with softkey K0), the command KBD CMODE can be used to turn on or off compatibility mode. ITF and Nimitz compatible softkeys are discussed in Chapter 2 of the Installing and Using manual.


A New Backspace

Under HP BASIC, the Backspace key was assigned to CHR$(255)&"B". This function does the same thing that the Left Arrow key does. HP BASIC is unique in this treatment of the Backspace key. For compatibility with the remainder of the computing community, HTBasic assigns a new function to the Backspace key. Pushing Backspace deletes the character to the left of the cursor. This function is named DEL LEFT and is equivalent to the function LEFT followed by DEL CHR. If you do not like this definition, you may be able to redefine the key using the CONFIGURE KEY statement. See Chapter 8 of the Installing and Using manual for more details. Under the DOS Version of HTBasic, the following statement will change the Backspace key to match HP BASIC:

CONFIGURE KEY 1 TO NUM("B")


Series 300 Bit-Mapped (CRTB) Displays

If you are using an HP 9816, 9836, or other HP computer with separate alpha and graphics hardware, some of the differences you find in HTBasic will be the same differences you would find moving to an HP 310 or another HP computer with a fully bit-mapped alpha/graphics display. Bit-mapped displays are driven by the CRTB Mode Driver. A CRTB display has only bit-mapped images. The ALPHA image is written into one or more of the graphic planes. One plane can be separated from the others for use solely for the ALPHA image. Or, all the planes can be merged for shared use between ALPHA and GRAPHICS. See SEPARATE and MERGE ALPHA in the Reference Manual.

When ALPHA and GRAPHICS are merged, ALPHA text is converted to graphic bits and written into the graphic planes, overwriting any graphics data that might be present. Therefore, ALPHA and GRAPHICS cannot be dumped separately. And when the ALPHA text is scrolled, any graphic data present will be scrolled also. This is the default mode for a CRTB display.

The SEPARATE ALPHA statement can be used to simulate 9836C displays with independent ALPHA and GRAPHICS screens. Either image can be turned on or off or DUMPed independently of the other. However, the number of colors available for graphics is cut in half.

CRTB Mode is the default for EGA, VGA, Super-VGA, and X Window System drivers. This mode gives the best HP 9000 emulation. Check Chapter 3, "CRT and Graphic Drivers," of the Installing and Using manual for more information. CRTB Mode is not supported on a CGA or Hercules display.


9836C (CRTA) Displays

The HP 9836C display is driven by CRTA Mode drivers. A CRTA display has distinct ALPHA and GRAPHICS images. Either the ALPHA or GRAPHICS images can be displayed, or both can be displayed at once, overlapping each other. The hardware for the two images is independent.

HTBasic uses CRTA mode on a CGA or Hercules display adapter. However, the hardware on these adapters does not support complete 9836 emulation. Unlike the 9836, which has fully independent ALPHA and GRAPHICS display capabilities, these display adapters use the same display memory for both text and graphics modes. When in a text mode, the display hardware maps the display memory as characters. When in a graphics mode, the display hardware re-maps the same display memory as pixels. This means that whenever a switch is made between modes, the contents of the other screen are lost.

The CRTA Mode Driver tries to overcome these hardware deficiencies in the following manner: in the graphics mode both GRAPHICS and ALPHA text are written into the graphics bitmap. The graphics image is lost when switching from graphics mode to text mode and back again. The ALPHA text is not lost, but is re-written into display memory after each mode switch. Because of these deficiencies, the CRTB driver is used by default if you have an EGA or VGA display adapter. Use the SEPARATE ALPHA command with CRTB mode to give the best 9836C emulation.


Other Video Circuitry Differences

A list of minor differences in video circuitry that you should be aware of follows:

•  Hercules and CGA adapters do not have COLOR MAP hardware.
•  The cursor does not blink in PC graphic modes or under X windows.
•  Underline is not supported by PC color display adapters in text modes.
•  Blinking is not supported in graphics modes.


Expanded Memory

Expanded memory, LIM, EMS, or bank-switched memory is not supported. Extended memory, the memory above 1 Megabyte, is supported in the DOS Version.


Processor

The instruction sets for the Intel x86 family of processors, Motorola 680x0 processors, Sun SPARCstation processors, HP Precision Architecture processors are all different. Since a CSUB contains processor code, a CSUB can not be moved from HP BASIC or HTBasic on one processor and executed under another. The same holds true for assembly routines called with WRITEIO 9827.


Speed

If you are a PC user and speed is critical to your application, the following suggestions may be helpful. PC users of HTBasic are encouraged to buy a processor with math instructions built-in (such as the 486 or 486DX), or to add a math coprocessor. The DOS Version of HTBasic runs in protected mode with a linear address space, and uses in-line math coprocessor instructions. Ask your local computer dealer if you can try HTBasic on the fastest 486 or Pentium computer he can lay his hands on to evaluate the performance possible with HTBasic. Such a system can meet the performance needs of most applications.


Clock

Timing resolution varies from version to version of HTBasic. Millisecond timing resolution is not available on the IBM PC. The PC clock runs at about 18.2 ticks a second, Thus, all timing functions within HTBasic have a best resolution of about 55 milliseconds. Under UNIX, HTBasic attempts millisecond resolution, but resolution is affected by the number of processes running.


HP-IB/IEEE-488

Outside the HP world, the HP-IB bus is known by the name IEEE-488 or GPIB bus. Most computers are not sold with an integral IEEE-488 interface. An HP compatible IEEE-488 interface card for the PC can be purchased from TransEra, either bundled with HTBasic or as a later upgrade. Various third-party IEEE-488 interfaces are supported. Contact TransEra for information on supported interfaces for the PC and other platforms running HTBasic.

The TransEra model HM900 IEEE-488 card gives full IEEE-488 compatibility. Other interfaces usually lack minor functionality. For example, PC IEEE-488 interface cards that use the NEC 7210 IEEE-488 controller chip are incompatible in the following areas: All READIO and WRITEIO registers are different. Bit 0, IFC, is not supported in STATUS register 5 or the ENABLE INTR mask. The REM and LOC bits of STATUS register 6 are not supported as well as the DAV, NDAC, NRFD, and IFC bits of STATUS register 7.


Character Set

The default character set used by the IBM PC and the Sun SPARCstation is different than the HP Roman-8 character set used by HP BASIC. The differences exist in characters CHR$(128) and above. In HTBasic, all characters from CHR$(128) through CHR$(254) are allowed in variable names. If you will be running a program with HP BASIC and HTBasic, you should restrict variable names to characters from CHR$(161) to CHR$(254) and the legal characters less than CHR$(128). Chapter 13, "International Language Support," contains information on converting from the HP character set, or setting up the PC to use the HP character set.


Shared Resource Manager (SRM)

Shared Resource Manager users should consider upgrading to Hewlett-Packard's SRM/UX. By replacing SRM servers with SRM/UX servers, DOS and UNIX computers can access the files on the server using NFS. PC-NFS is available from Sun. NFS for UNIX platforms is available from the workstation vendor. HTBasic is also compatible with most industry standard networks, such as NetWare and LAN Manager.


Miscellaneous Differences

On the PC, support for the Centronix/Parallel Printer Interface has been added. The interface select code for LPT1 is 10, for LPT2 is 12. These can be changed if needed (see Chapter 12, "Other I/O Destinations").

The serial interface has been enhanced with XON/XOFF flow control. It is enabled by default. If you are porting existing programs that transfer binary data or ^S and ^Q characters as part of the data, you should turn off XON/XOFF flow control and turn on hardware handshaking with the statements:

CONTROL 9,100;0
CONTROL 9,5;0
CONTROL 9,12;0

The maximum line number in HTBasic has been increased from the HP limit of 32766 up to 65534. If you plan on also running a program on an HP computer, you should not use line numbers over 32766.

The maximum length of a line, in general, is the same as HP BASIC. However, in rare instances (such as a program with hundreds of variable names and a program line with little used operands and thirty or more variable references), it is possible that a line of legal length in HP BASIC will be considered too long in HTBasic. Such a line will generate an error when entered. The error is extremely rare; to correct the error, divide the statement into two statements.


HP ASCII File Problem

The Hewlett-Packard BASIC Language Reference manual entry for "ENTER" states that "data should be entered into variables of the same type as those used to output it." This general rule applies to HTBasic as well, and if violated can produce unexpected results. Consider the following program:

10   CREATE "TEMP",1
20   ASSIGN @I TO "TEMP";FORMAT ON
30   OUTPUT @I;"1,2"
40   OUTPUT @I;"3,4"
50   RESET @I
60   ENTER @I;A,B
70   PRINT A,B
80   ASSIGN @I TO *
90   PURGE "TEMP"
100  END

This program violates the matching-type rule by outputting strings and then entering numerics. Intuitively, you expect line 70 to print 1 and 2, which it does. When line 10 is changed to "CREATE BDAT", the same result is produced. But if line 10 is changed to "CREATE ASCII", then HP BASIC prints 1 and 3. Whether or not you consider this a bug in HP BASIC, it is a discrepancy that has been corrected in HTBasic. If you have written programs that use ASCII files and violate the matching-type rule, you should correct them before running them with HTBasic. If your program must run with both HP BASIC and HTBasic, you must either adhere to the matching-type rule, or use another file type.


File Systems

HTBasic uses the native file system of whatever operating system it is running under. The DOS versions of HTBasic (and the Windows version when running under DOS) use the DOS FAT file system. Under UNIX, HTBasic uses the UNIX file system. Under NT, HTBasic can use FAT, NTFS, or HPFS file systems. HTBasic does not support the LIF file system.

A primary difference between HP BASIC and HTBasic is that HP BASIC/WS does its own file I/O, while HTBasic has the operating system do all file I/O. This has advantages and disadvantages. Any disk, diskette, network, or device accessible through the file system is accessible from HTBasic. However, since HP has not added HP LIF capabilities to its version of MS-DOS, you can't use HP LIF diskettes, HP-IB disks, tape drives, or SRM from HTBasic. Maybe HP will correct this situation in the future.

A couple of warnings are in order about the way most operating systems work. If a file is currently ASSIGNed, the operating system buffers some data in memory to make I/O faster. This buffering can produce unexpected results if the same file has multiple I/O paths ASSIGNed to it concurrently. Also, you should not remove a diskette, or turn the power off while a file is ASSIGNed.

Under DOS, NT and UNIX, HP BASIC and HTBasic maintain compatibility with LIF file types by keeping a special file header for typed files (BDAT, LIF ASCII, and PROG files). The extra information that must be stored for these file types is kept in the header. The header is kept totally hidden from BASIC programs. However, to programs outside HTBasic, the header will be accessible as the first bytes of the file. Any files without the special header are known as "ordinary files". In a CAT listing, the file type is blank for ordinary files or gives the operating system (i.e., "DOS" or "HP-UX").

In addition to HTBasic file headers, HTBasic can recognize and use HP LIF headers. This allows networked computers to directly interchange data between Series 200/300 systems running HP BASIC and systems running HTBasic. The new CONFIGURE CREATE {"HP" | "HTB"} statement allows the program to specify the type of file header to use when creating a new BDAT or LIF ASCII file.


LIF ASCII vs. Ordinary ASCII

Early versions of HP BASIC did not have a file type that matched DOS ASCII or UNIX ASCII files. Starting with BASIC 5.0, it does have an ordinary, "vanilla" file type that can hold DOS ASCII or UNIX ASCII data. With HP BASIC/WS or HP BASIC/UX, ordinary files are called "HP-UX" files. With the Viper Card, ordinary files are called "DOS" files. No special header or other embedded information is placed in ordinary files. An ordinary file written with FORMAT ON is a DOS ASCII file. An ordinary file written with FORMAT ON, EOL CHR$(10) is a UNIX ASCII file. Use the CREATE statement to create an ordinary file. In a CAT listing, an ordinary file is listed with the file type blank, or gives the name of the operating system ("DOS" or "HP-UX").


DOS (FAT) File System

The following sections describe some of the differences between the DOS (FAT) file system and the HP 9000 Series 200/300 BASIC Logical Interchange Format (LIF) file system. The following discussion is not meant to be a substitute for your DOS manual. You should read it for complete information on the topics presented here.

The FAT file system, like the HP-UX or Shared Resource Manager (SRM) file system, is a Hierarchical File System (HFS). An understanding of HFS, UNIX, or SRM file systems may aid you in understanding the FAT file system.


DOS (FAT) File Specifier

Under DOS, a file specifier has the form:

[d:] [directory path] filename[.ext]

where:

d: is the drive letter. Usually this is A: and B: for the two diskette drives, and C: for the hard disk. Higher drive letters, D:, E:, etc., usually refer to RAM (MEMORY) disks, CD-ROMs, or network drives. This part of the file specifier corresponds to the msus of the HP file system, but is included on the front, not the end of the file specifier. It is optional, and if omitted, the current (or default) drive is used.

directory path is optional. It is explained below.

filename is the the main part of the file specifier. It may be one to eight characters long. The following characters are not allowed to be in a filename: ."/\[]:|<>+=;, and control characters whose ASCII value is less than the space character. All other characters are legal. If lowercase letters are used in a filename they are converted to uppercase by DOS. Thus, you cannot have a file named "AbC" and another file named "aBC". DOS will consider both names to be "ABC". Be aware that a DOS file specifier is often referred to simply as a filename.

ext is the filename extension. The same characters that may be used in a filename may also be used in an extension. Certain conventions are used for filename extensions. Most of them are arbitrary, with a few exceptions noted below. Some conventional extensions are:

Extension	Conventional Use
.BAS	BASIC program
.BDT	BDAT file
.ASC	ASCII file
.DAT	BDAT, or DOS data files
.TXT	text files
.LIS	text files, or compiler listings
.LST	another common listing file extension
.DOC	A DOS ASCII file containing documentation
.BAT	DOS batch files MUST have this extension
.COM	An executable DOS command or program
.EXE	An executable DOS command or program. DOS commands
and programs MUST have one of these two extensions

Note that compared to an HP file specifier, the msus is replaced by a drive letter and moved from the back to the front. Also, an extension has been added, and no password is used or available. While DOS does not have passwords, it does have some access capabilities (similar to SRM access capabilities). These are discussed below. If passwords are present, they will be ignored.

If an HP-style msus is present, it can be translated to a DOS path if specified by the CONFIGURE MSI statement. If no matching translation can be found, an error is returned. The CONFIGURE MSI statement has been added to HTBasic to allow HP style file specifiers to be used with a DOS file system. If DOS style file specifiers are used, then the CONFIGURE MSI statement is not needed.


DOS Directory Path

The DOS file system is "tree" structured, almost exactly like the HFS and SRM file systems. If you are familiar with the HFS file system, the following differences may be instructional. The "/" character of the HFS file system is replaced with "\" in the DOS file system. Passwords do not exist in the DOS file system and will cause an error if included in a directory name.

The file system is organized as a tree. Actually, it is usually thought of as an upside-down tree. The top of the tree is, thus, the root. (Not roots. Directory trees are considered to have only one root, and the term trunk is usually not used.) The tree is composed of directories and files. Each directory may contain files and additional directories, which act like branches down the tree. Directory names follow the same rules as filenames with extensions.

A directory path is the path you climb through in the tree to get from the root of the tree to a certain directory. It consists of the names of each directory that must be climbed through in order to get to that certain directory, separating the directory names with the backslash "\" character. If you have not already, you will find it helpful to read the material in your DOS manual concerning directories.


DOS File Types and Access Capabilities

The DOS file system stores certain information about a file in addition to storing information in the file. This information consists of:

•  file name
•  number of bytes in the file
•  modification date and time
•  access capabilities: hidden, read-only, system
•  location on the disk of the file contents

DOS does not store a record length or a file type. It does have access capabilities, although they are different from the SRM access capabilities. The access capabilities are called "attributes" by DOS and may be changed by the DOS ATTRIB command. They may also be changed by the HTBasic PROTECT command. The meanings of the attributes are:

Attribute	Meaning
hidden	the filename is not shown in a disk catalog,
although the file is there
read-only	the file may be read, but not written or deleted
system	the file is a system file


DOS Devices

HP BASIC accesses devices through interface and device select codes. The same is true of HTBasic. However, DOS also allows access to devices as if they were files. Special names are given to devices by DOS, and when used in the place of a filename, access a device instead of a file. These names are called DOS Device Names and are typically: CON, AUX, COM1, COM2, PRN, LPT1, LPT2, and NUL. Often, data acquisition hardware for the PC comes with a DOS device driver. To access such a data acquisition board, treat it as you would a file and use ASSIGN, OUTPUT, and ENTER.


DOS Wildcards

The question mark "?" and the asterisk "*" have special meaning to DOS. They are called wildcards and are used in DOS commands like DIR and the HTBasic CAT command in order to select more than one file. A filename with wildcard characters in it will be compared with existing filenames using special rules and all filenames that "match" will be selected. These are the rules used to match an actual filename with wildcards:

1. The "?" character will match any one character in the same position of an actual filename. For example, the string "?AT" will match the strings "CAT", "BAT", "MAT", or any other string three letters long that has an "A" as the second letter, and "T" as the third letter.

2. The "*" character will match zero or more characters starting at that position. For example, "*" will match all filenames. "*.BAS" will match all filenames that have the ".BAS" extension.


Keyword Differences

The following sections present, by keyword, various implementation differences between HTBasic and HP BASIC. Most differences are the result of hardware differences, file system differences, or extensions in HTBasic. The Reference Manual can be consulted for the full explanation of keywords mentioned here. In some cases, DOS or UNIX commands that relate to BASIC commands are given. This may help you learn DOS or UNIX faster by associating functionality with commands you already know.

Some differences exist because of enhancements TransEra has made. Many enhancements can be included in programs that run under both HP BASIC and HTBasic, if you are careful. One approach is to hide statements that won't parse under HP BASIC in OUTPUT KBD statements:

OUTPUT KBD;"CONFIGURE PRT TO 701"&CHR$(255)&"E";

Another approach is to set up a section of code that is executed only by HTBasic. When you GET the program under HP BASIC, the lines with HTBasic syntax enhancements will be commented out and ignored by HP BASIC:

10  INTEGER Htbasic
20  Htbasic=SYSTEM$("VERSION:HTB")<>"0"
30  IF Htbasic THEN
40    CONFIGURE DUMP TO "HP-PCL"
50    CONFIGURE PRT TO 701
60  END IF
70  END

When porting programs between HP BASIC and HTBasic, note the differences for the following keywords.


ALLOCATE

Under HTBasic, GOSUB and ALLOCATE use the same stack. Intermixing these statements can cause changes in available memory that are different from HP BASIC.


ASSIGN

When an ASSIGN fails, the previous state of the I/O path is not preserved. Also, the CONVERT and PARITY options are not implemented.

Under DOS, if changes are made to an ASSIGNed file, the directory entry is not updated until the file is closed. DOS buffers reads and writes to disk. You should not remove a diskette or turn the power off while a file is ASSIGNed. Exchanging diskettes while a file is ASSIGNed on the first can destroy the next diskette. Two I/O paths ASSIGNed simultaneously to the same file can produce slightly different results than HP BASIC, depending on the buffering DOS does.

The HTBasic ASSIGN includes two new options, FORMAT LSB FIRST and FORMAT MSB FIRST, to specify byte ordering of binary numeric data transfers. This provides the ability to do binary transfers with any device or computer, regardless of the byte ordering that device uses.


ATN2

ATN2 is a new HTBasic function.


BEEP

Sound generation capabilities vary from version to version. On computers that do not provide control for variable frequency sound generation, BEEP generates a beep or bell sound. The range of the duration and frequency are subject to the limits of the computer hardware. Contrast the following capabilities with HP BASIC. HP BASIC rounds the frequency value to a multiple of 81.38 Hz and supports a range of 81 Hz to 5.208 KHz.

On the IBM PC, the period (not the frequency) is rounded to a multiple of 0.838 micro-seconds. The range of frequencies is 40.7 Hz to 32.767 KHz.

Under UNIX, the -beep command line switch determines whether the BEEP statement uses the console to produce the tone, or whether it uses the CRT driver to produce the tone (in some driver-specific manner). By default, the console is used to produce the tone. This is not always the appropriate behavior, as would be the case when running remotely.

Under the Sun Version, the console uses the /dev/audio device to produce the tone. The period is rounded to a multiple of 125 micro-seconds. Consequently, the number of frequencies is very limited. For example, above 1000 Hz the only frequencies available are 1143, 1333, 1600, 2000, 2667, and 4000.

If the X Windows CRT driver is producing the tone, then the results vary according to the X Server. OpenWindows 2.0 always produces a tone of 2400 Hz, although the duration of the BEEP statement matches the duration specified. HP-VUE produces the requested frequency, but allows the program to continue immediately while the tone is sounding.


BINEQV/BINIMP

These are new HTBasic functions.


BLOAD/BSTORE

The functionality of the HP BLOAD, BSTORE compiled subroutines is an integral part of the HTBasic language and does not require CSUBs. See the GLOAD/GSTORE section in this chapter for more information.


BUFFER

In HTBasic, it is usually incorrect to access numeric data in a buffer through the array name. ENTER and OUTPUT should be used instead.


CAT

The format of CAT output varies according to operating system. This behavior is compatible with HP BASIC. The CAT statement supports the use of wildcards. Again, wildcard interpretation varies by operating system. See CAT and WILDCARDS in the Reference Manual for more information.

Under DOS, HTBasic does not allow wildcards to be turned off as HP BASIC allows. Under UNIX, WILDCARDS are ON by default and the escape character is "\". HP BASIC uses wildcards as a primary filter and the SELECT option as a secondary filter in choosing filenames to display. HTBasic is designed to be used with one or the other. Use wildcards or the SELECT option, but not both.


CDIAL

At the time of this manual printing, CDIAL was not supported. However, user demand is monitored and it will be implemented if demand warrants it.


CHECKREAD

Under DOS, this command is equivalent to the DOS VERIFY command. Under UNIX, this command is ignored.


CHGRP and CHOWN

CHGRP and CHOWN are useful with an operating system like UNIX in which files are owned by individuals and groups. These commands allow a user with the appropriate privilege to change or assign ownership of files. These commands are not used for DOS. Under any version of HTBasic, the editor will allow these statements to be entered, and the syntax checker will check them for correctness.


CINT

CINT is a new HTBasic function.


COMMAND$

COMMAND$ is a new HTBasic function.


CONFIGURE

The CONFIGURE statement is an enhancement to HTBasic that allows the environment to be customized to a user's preference, or to match his HP hardware. The CONFIGURE statement is explained in the Installing and Using Manual.


CONTROL/STATUS

Depending on the hardware interface, some CONTROL and STATUS registers may be different. The PC serial hardware and TransEra's GPIB-900 board have registers that are compatible with the HP registers. For other interfaces, consult the interface register documentation.

TransEra has added capabilities to several of the standard interfaces. The additional registers resulting from these enhancements are always numbered 100 and above. In some instances HTBasic can pass arrays to and from a single register. This capability is used for things like gain control lists in data acquisition drivers.


COPY

HTBasic does not support the copy of a full disk to another disk. Use the operating system for full disk copies. Under DOS you can use the DOS "DISKCOPY" or "XCOPY" commands. The DOS XCOPY command (DOS 3.2 and later) is an extended COPY command that, among other things, allows you to copy entire disks when the disk sizes are not the same. Under UNIX, commands like "tar" and "cpio" might be used. The DOS COPY command and the UNIX mv command are used to copy individual files. If wildcards are included in the command, then several files can be copied with a single command.


CREATE

Because DOS and UNIX support extendible files, the number of records specified in the CREATE statement is ignored. An invalid number does not generate an error as it will under HP BASIC. Programs that depend on errors occurring by writing past the last specified record will not function correctly, as HTBasic will simply extend the file as needed. Programs that depend on the pre-allocation of the requested records should write dummy data at the time the file is CREATEd. Under DOS, it is sufficient to write data in the last record; under UNIX, the entire file must be written.

Don't confuse a LIF ASCII file, created with CREATE ASCII, with a DOS ASCII or UNIX ASCII file, created with CREATE. See CREATE in the Reference Manual for more information.

Use the CONFIGURE BDAT MSB FIRST statement before creating BDAT files that will be moved back to HP BASIC.


CREATE DIR

This command is exactly like the HP BASIC command of the same name. It is the equivalent of the DOS MD or MKDIR commands or the UNIX mkdir command.


DEF FN

Nested I/O is not allowed under HP BASIC. For example,

10  PRINT FNX
20  END
30  DEF FNX
40    PRINT "DEBUG:START"
50    RETURN 0
60  FNEND

will produce an error under HP BASIC. At the time of this manual printing, nested I/O does not return an error under HTBasic but should not be used because future improvements may make it illegal.

HTBasic limits the depth that recursion can occur. The depth is limited by the size of the processor stack, not the BASIC workspace size. At the time of this manual printing, the recursion limit is for the DOS Version. Under UNIX, the limit is some large number, limited by the size of the swap file or other operating system quotas. Under NT, the limit is about 1800.


DELSUB

HTBasic allows a string variable to specify the name of the subprogram or function to delete.


DUMP

HP BASIC supports only Hewlett-Packard printers, but HTBasic supports several types of printers. For this reason, you may need to tell HTBasic what language to use before doing the DUMP. On a PC, the default language is "EPSON", which supports both IBM and Epson graphic printers. Under UNIX, the default language is PostScript. If you are going to make screen dumps to another type of printer, you must first use the CONFIGURE DUMP statement. You may find it convenient to include this statement in your AUTOST file. Chapter 4, "Printer and Image File Drivers," of the Installing and Using manual explains what languages are supported and how to select them.

When DUMPing to a printer, the ratio of the image size on the printer may not match that on the screen. This is caused by non-square pixels on the display or on the printer. CGA, EGA, and Hercules display adapters, and Epson and IBM printers are common devices with non-square pixels. The VGA display adapter and HP-PCL printers have square pixels and, used together, will not produce distortion.


EDIT

EDIT SUB and EDIT FN are extensions in HTBasic. Several new edit functions are also included. See "OUTPUT KBD", later in this chapter.


ENABLE INTR

Depending on the hardware interface, some ENABLE INTR mask values may be different. On the PC, interfaces supported by the "SERIAL" and TransEra "GPIB" board drivers have interrupt masks that are compatible with the HP masks. For other interfaces, consult the interface register documentation.


ENVIRON$

ENVIRON$ is a new HTBasic function.


ERRDS

At the time of this manual printing, ERRDS was not supported. However, user demand is monitored and it will be implemented if demand warrants it.


ERRM$

HTBasic error messages are usually similar to those in HP BASIC. Programs that depend on ERRM$ returning the exact same message as HP BASIC should be modified accordingly. In particular, where an HP BASIC error message has seemed less descriptive than it should be, HTBasic returns a more descriptive message.


ERRN

Any error number of 2000 or greater is an HTBasic extensions to HP BASIC. Not all errors that can occur under HP BASIC can occur under HTBasic. The Reference Manual contains a list of errors that can occur.

In general, and whenever possible, the error numbers returned for errors are the same as those returned by HP BASIC. But in some instances the operating system or environment in which HTBasic runs makes it impossible or impractical to return the same number.


EXECUTE

The EXECUTE statement has been added to run operating system commands or other programs while HTBasic is running. See Chapter 4, "Program Flow Control". The DOS Version requires that memory be reserved for EXECUTEd commands. Use CFIG386, described in the Installing and Using HTBasic on the DOS Version manual, to reserve memory for the program or DOS command.


FIX

FIX is a new HTBasic function.


FRACT

HTBasic allows the FRACT of a complex value, returning the fractional part of the real part of the complex value. HP BASIC gives error 620.


FRE

FRE is a new HTBasic function.


GESCAPE

Only HP BASIC operation selectors 1 to 6 are supported by GESCAPE. Often, where operation selector 7 is used, MERGE or SEPARATE ALPHA can be used instead. Operation selectors greater than 99 are enhancements to HTBasic.


GET

HTBasic turns lines with syntax errors into comments by inserting "!*" instead of just "!" after the line number. This allows FIND "!*" to quickly identify lines needing corrections.


GLOAD/GSTORE

The HP rule that images be GLOADed on the same display and with the same write-enable mask that was used when the image was GSTOREd applies to HTBasic as well. In particular, don't think that you can GSTORE on an HP BASIC display and GLOAD on an HTBasic display.

HTBasic GLOAD and GSTORE have been enhanced with the capabilities of HP BASIC's BLOAD and BSTORE subprograms. These capabilities allow rectangular blocks of the screen to be stored or loaded. The following subprograms can be used in place of the BLOAD and BSTORE subprograms for users that want to continue calling BLOAD/BSTORE instead of switching to the new GLOAD/GSTORE syntax:

10    SUB Bstore(INTEGER Int_array(*),W,H,OPTIONAL Rule,REAL X,Y)
20      SELECT NPAR
30      CASE 3
40        GSTORE CRT,Int_array(*),W,H
50      CASE 4
60        GSTORE CRT,Int_array(*),W,H,Rule
70      CASE 5
80        WHERE X0,Y0
90        GSTORE CRT,Int_array(*),W,H,Rule,X,Y0
100     CASE 6
110       GSTORE CRT,Int_array(*),W,H,Rule,X,Y
120     END SELECT
130   SUBEND
140   SUB Bload(INTEGER Int_array(*),W,H,OPTIONAL Rule,REAL X,Y)
150     SELECT NPAR
160     CASE 3
170       GLOAD CRT,Int_array(*),W,H
180     CASE 4
190       GLOAD CRT,Int_array(*),W,H,Rule
200     CASE 5
210       WHERE X0,Y0
220       GLOAD CRT,Int_array(*),W,H,Rule,X,Y0
230     CASE 6
240       GLOAD CRT,Int_array(*),W,H,Rule,X,Y
250     END SELECT
260   SUBEND

Note that only rule 3, replace, is currently supported.


GRAPHICS INPUT IS

Both HP BASIC and HTBasic do an implicit GRAPHICS INPUT IS assignment for you if you attempt to use graphic input statements before an explicit GRAPHICS INPUT IS. The difference is that HTBasic does the implicit GRAPHICS INPUT IS as soon as HTBasic is started, and HP BASIC waits until the first graphic input statement is executed. The only known effect of the different approaches is that under HP BASIC, a SYSTEM$("GRAPHICS INPUT IS") returns "0" until the first graphic statement is executed and HTBasic returns the correct value anytime.


HELP

The HELP statement is a new HTBasic statement. It provides on-line help for all language statements. The Reference Manual has been compressed and is stored in a file. Just enter HELP followed by the keyword of interest and HTBasic brings up the Reference Manual page for the requested keyword. You no longer have to run and get the Reference Manual when you have a question on statement syntax or functionality.


HIL

At the time of this manual printing, HIL related statements were not supported. However, user demand is monitored and they will be implemented if demand warrants it.


IMAGE

Entering data from a string using

ENTER L$ USING "Y"

will always use the internal byte ordering of the computer. For PCs and compatibles, the byte ordering is LSB FIRST. For Sun SPARCstations and HP Workstations, the byte ordering is MSB FIRST. This limitation applies to ENTER/OUTPUT with strings only. With devices, the byte ordering can be selected in the ASSIGN statement.


INITIALIZE

HTBasic does not support INITIALIZE. To initialize a new LIF disk, use "INITIALIZE" on an HP BASIC workstation. To initialize a new DOS disk, use the "FORMAT" command under DOS. To initialize a new Sun floppy disk use the "fdformat" command under SunOS 4.x. To initialize a new HP-UX floppy disk, use the "mediainit" and "newfs" commands under HP-UX.

RAM disks are not supported with the INITIALIZE ":MEMORY,0" command. Many excellent RAM disk programs are available for the PC that make the RAM disk available to all DOS programs, including HTBasic. These programs can usually make RAM disks in conventional, expanded, or extended memory. A simple one is provided with DOS and is called VDISK.SYS or RAMDISK.SYS.


INP/INPW

INP and INPW are new HTBasic functions for communicating with devices having no HTBasic device driver. They are not supported under protected mode operating systems like UNIX.


KBD CMODE

HP BASIC and HTBasic both use KBD CMODE ON for Nimitz keyboard softkey compatibility. The Nimitz keyboard is used on the 9836 and has ten softkeys, the lowest of which is labeled k0. The softkey labels are displayed at the bottom of the screen in two rows, each row containing five labels and each label 14 characters wide.

The difference between HP BASIC and HTBasic's implementation of KBD CMODE ON is that HTBasic exactly emulates the screen format for the labels, while HP BASIC uses an emulation that gives physical correspondence with the ITF 4-2-4 softkey layout.


LEXICAL ORDER

Several extensions are present in the LEXICAL ORDER statement of HTBasic to allow user definition of upper/lowercase rules for languages that are not built-in. The rules can also be loaded from a file.


LINE TYPE

In the LINE TYPE statement, the repeat length is ignored by most graphic drivers.


LIST BIN

LIST BIN is programmable in HTBasic, but not in HP BASIC.


LOAD

HP BASIC PROG files and HTBasic PROG files are not compatible. To move programs between the two environments, use ASCII program files.


LOAD BIN

The LOAD BIN statement has been enhanced to allow software switches to be passed to device drivers. HP BASIC BIN files are not compatible with HTBasic.


LOADSUB

HTBasic allows a string variable to specify the name of the subprogram or function to load.


MASS STORAGE IS

The current "MASS STORAGE IS" on a DOS or UNIX file system includes not only the device, but also the current directory. In other words, it specifies not only which tree (device) you are in, but where in the tree (current directory) you are. The DOS command CD and the UNIX command cd change the current directory when not running HTBasic.


OUT/OUTW

OUT and OUTW are new HTBasic statements for communicating with devices having no HTBasic device driver. They are not supported under protected mode operating systems like UNIX.


OUTPUT KBD

Three editor functions have been added to HTBasic and should not be used in programs that will be executed with HP BASIC: DEL LEFT, NEXT WORD, and PREV WORD. Otherwise, all the two-character function key sequences ( CHR$(255)&CHR$(X) ) used by HP BASIC are compatible with HTBasic. If multiple statements are output in a single OUTPUT KBD statement, they are all executed before the next BASIC line. HP BASIC sometimes intermixes the execution with multiple BASIC lines, based on the presence or absence of "closure keys."


PERMIT

PERMIT is used under UNIX to set the permissions (mode) of a file, directory, or device. Permissions specify who can read, write, or execute a file, and who can search a directory. To change file attributes under DOS, use the PROTECT statement.


PHYREC, Phyread, Phywrite

The PHYREC utilities under HP BASIC allow physical disk sectors to be read or written. Such access usually provides enhancements or file utilities for LIF formatted disks. Programs using Phyread and Phywrite most likely will not work under DOS or UNIX, and in fact will probably destroy the files on the disk involved. DOS and UNIX provide methods of accessing physical disk sectors, but no PHYREC utilities are supplied with HTBasic because of the complexity and danger involved.


PLOTTER IS

Under HP BASIC, PLOTTER IS 3,"INTERNAL" is equivalent to PLOTTER IS 6,"INTERNAL" unless the HP 98546 Display compatibility Interface is installed. Under HTBasic, 3 selects CRTA mode and 6 selects CRTB mode (see the Installing and Using manual). If this is not your intention, you need to do what HP recommends for users of the 98546: use PLOTTER IS CRT,"INTERNAL" instead of 3 or 6.

Both HP BASIC and HTBasic do an implicit PLOTTER IS assignment for you if you attempt to use graphic statements before an explicit PLOTTER IS. The difference is that HTBasic does the implicit PLOTTER IS as soon as HTBasic is started, and HP BASIC waits until the first graphic statement is executed. The only known effect of the different approaches is that under HP BASIC, a SYSTEM$("PLOTTER IS") returns "0" until the first graphic statement is executed and HTBasic returns the correct value anytime.

HP BASIC supports only "INTERNAL" and "HPGL" graphic languages. HTBasic supports loadable graphic device drivers so it is not limited to these two choices. HTBasic also allows clip-limits to be specified when output is directed to a device, allowing use of plotters or printers that are incapable of returning p-points.


PRINT

HTBasic has been extended to allow the displacement of the attribute and color control characters that normally have the values CHR$(128) to CHR$(143). Since the PC has characters in this range that sometimes need to be displayed, HTBasic has the capability of moving the range with the statement CONTROL CRT,100;1.


PRINT LABEL and READ LABEL

PRINT LABEL and READ LABEL are used to set and read the volume label of a disk drive. Under UNIX, labels are not supported. Under DOS, HTBasic does not support PRINT LABEL; you must use the DOS "LABEL" command. To change the label of a disk from an HTBasic program, use the EXECUTE "LABEL x:" command.


PROTECT

PROTECT is used to set LIF file passwords under HP BASIC and DOS file attributes under HTBasic. It is not used by UNIX versions. To change file permissions under UNIX, use the PERMIT statement. A special form of PROTECT is used by DOS Versions of HTBasic to change file attributes. The syntax is

PROTECT file-specifier, protect-code

where protect-code is a string containing zero or more of the following characters:

Character	Meaning
(none)	no protection
R	read-only: File cannot be written or deleted.
S	system file: For the most part, this attribute has
no meaning.
H	hidden: File will not be listed by a CAT command.

If a character is not included, that attribute is cleared. If the string is blank, all attributes are cleared.


PRT

Most PC printers are connected to the parallel printer interface. For this reason, under DOS, PRT returns the value 10 instead of 701. Programs with statements that use PRT explicitly, such as "PRINTER IS PRT" need not be changed if a parallel printer is used on the PC. To change PRT back to 701, for IEEE-488 printers at primary address 1, use the statement "CONFIGURE PRT TO 701". You may find it convenient to include this statement in your AUTOST file. This statement is not necessary if you use the value 701 (or any other value) explicitly.


PURGE

PURGE is similar to a combination of the DOS DELETE and RD or RMDIR commands and the UNIX rm and rmdir commands. Unlike DELETE, PURGE will only delete one file at a time, and will also delete directories. PURGE will not delete a directory unless there are no files in that directory. Also, DOS will allow you to PURGE an ASSIGNed file. The actual PURGE takes place after the file is closed.


QUIT

The QUIT command exits HTBasic and returns you to the operating system command processor or shell. Any program or data in memory is lost. You should store any program changes before quitting.


READIO/WRITEIO

READIO/WRITEIO access hardware registers directly, and therefore, if the interface hardware is different than the hardware on an HP BASIC Workstation, the READIO/WRITEIO registers will not be compatible. TransEra supplies a PC IEEE-488 bus controller card that duplicates the Series 200/300 HP-IB READIO and WRITEIO registers. Other IEEE-488 bus controller cards are not usually completely compatible. For other interfaces consult the interface register documentation.

Several special un-documented READIO/WRITEIO select codes have existed in HP BASIC for many years. These select codes are now documented and allow peeking and poking memory locations, and executing machine language subroutines.


RENAME

RENAME is used to change the name of a file, but can also be used on some systems, including DOS and UNIX, to move a file from one directory to another directory on the same disk. RENAME is similar to the DOS RENAME command and the UNIX mv command.


SAVE

The SAVE statement in HTBasic can be set to save programs in either ordinary ASCII or LIF ASCII. This is done with the CONFIGURE SAVE ASCII statement. (DOS ASCII and UNIX ASCII are ordinary ASCII files.)


SCRATCH BIN

SCRATCH BIN is not supported for HTBasic binaries. You may QUIT and re-start HTBasic to scratch all binaries.


SEPARATE ALPHA

HP BASIC assigns green to the alpha plane by assigning green to pens 8 through 15. HTBasic assigns white. If you prefer green, or some other color, you may explicitly set pen values 8 to 15 to the color desired.


SET ALPHA/DISPLAY MASK

At the time of this manual printing, SET MASK was not supported. However, user demand is monitored and it will be implemented if demand warrants it. Currently, MERGE/SEPARATE ALPHA are the supported methods of changing the masks.


SET CHR

At the time of this manual printing, SET CHR was not supported. However, user demand is monitored and it will be implemented if demand warrants it.


SET TIME/TIMEDATE

HP BASIC/UX keeps a BASIC time that is separate from the actual system time. SET TIME and SET TIMEDATE, specified without any time value, resynchronizes the two. Since HTBasic avoids this problem under UNIX, SET TIME and SET TIMEDATE change the actual UNIX system time. SET TIME and SET TIMEDATE, with no time value, is ignored. Remember that you must be the super user (root) in order to successfully change the UNIX system time.


SOUND

At the time of this manual printing, SOUND was not supported. However, user demand is monitored and it will be implemented if demand warrants it.


STATUS

STATUS @Iopath,2 always returns a 4.

STATUS @File,3 returns the current length, not the CREATE length. This is because files are extendible under DOS and UNIX.

The STATUS() function (as opposed to the STATUS statement) is an addition to HTBasic. Any STATUS or CONTROL registers greater than 99 are also additions.

As in HP BASIC, STATUS register 0 of interface cards contains the card ID. Interface cards that are available on a PC, but not on an HP BASIC Workstation are identified with ID numbers greater than or equal to 300.


STORE

HP BASIC PROG files and HTBasic PROG files are not compatible. To move programs between the two environments, use ASCII program files.


STORE SYSTEM

In HP BASIC this statement stores a copy of the operating system with all loaded BINs already linked in. Under HTBasic this is not possible. Use AUTOST to load HTBasic device drivers.


SYMBOL

LORG 5 moves the symbol origin from (0,0) to (5,8). In HP BASIC it moves the origin to (4.5,7.5).


SYSBOOT

HTBasic does not support SYSBOOT, which under HP BASIC reboots the computer. Since HTBasic runs as a guest of the operating system, it is considered inappropriate to reboot the computer. Under some operating systems, rebooting the computer inappropriately can cause loss of data.


SYSTEM$

Minor differences in some SYSTEM$ responses exist where appropriate to reflect the hardware differences and the DOS or UNIX operating system. See SYSTEM$ in the Reference Manual for more details.

The SYSTEM$("DISP LINE") function is an HTBasic extension that returns the present contents of the display line.

The SYSTEM$("VERSION:HTB") function returns the HTBasic version description, for example, "DOS Version Release 5.0". This function can be useful for programs that run on both HP BASIC and HTBasic systems, enabling them to determine which system they are currently running on. The following example sets a variable according to the system running the program:

10  SUB Which_system
20    COM /Which_system/Htbasic,Hpbasic
30    IF SYSTEM$("VERSION:HTB")="0" THEN
40      Hpbasic=1
50    ELSE
60      Htbasic=1
70    END IF
80  SUBEND


TIMEZONE

HTBasic does not require this statement and will return an error if an attempt is made to execute it. The editor will allow it to be entered, and the syntax checker will check it for correctness to allow you to develop programs and run them under HP BASIC. HP BASIC requires this statement for two reasons: 1) HP BASIC/UX keeps a time clock independent of the UNIX time, and 2) it is possible to boot HP BASIC/WS on a computer whose real-time clock is set to Greenwich Mean Time (GMT).


TRANSFER

Not all devices or versions of HTBasic support TRANSFER.


WRITEIO

See the explanation under READIO for some differences. Other processors can not execute the Motorola code accessed by WRITEIO 9827. The code must be rewritten.


XREF

HTBasic allows a string variable to specify the name of the subprogram or function.


Language Elements
Chapter 3
Language Elements

This chapter contains conceptual information that you need to understand before attempting to write programs using HTBasic. The basic elements of the language are explained: program lines, labels, keywords, contexts, I/O paths, constants, variables, arrays, and data types.


Program lines

An HTBasic program is a series of instructions. These instructions are in the form of program lines. The general form of a program line is:

line_number [ label: ] statement [ !comment ]


Line Numbers

Each HTBasic program line requires a unique line number at the beginning of the line. Line numbers must range from 1 to 65534. HTBasic ignores leading zeros, spaces, and tabs before line numbers. Line numbers are used to:

•  indicate the order of statement execution
•  provide control points for branching
•  help in debugging and updating programs
•  indicate the location of run-time errors


Line Labels

Line labels may optionally follow any line number. The use of line labels results in more structured programming. If all line references use line labels, the line numbers can effectively be ignored. Line references to labels are unaffected by line numbering. A line label can not be the only thing on a line; you must include a statement, even if it is just a comment tail "!".


Statements

A program statement is the smallest complete program unit. It is made up of HTBasic keywords, operators and operands. The Reference Manual details the syntax for each program statement.

The maximum number of characters allowed in a program line is 255. A program line longer than 80 characters (or the screen width) will wrap to the next line. No continuation character is necessary. In EDIT mode, only the first 160 characters (or twice the screen width) of a line are displayed. If a line contains more than 160 characters, an asterisk, "*", will follow indicating that there are more characters that are not displayed.


Comments

An optional comment may be added to any program statement by starting the comment with an exclamation mark "!". The characters following the exclamation mark will be retained in the program as a comment and are ignored during the execution of the program. Comments are not moved by the INDENT statement.


Keywords

Certain words have a special meaning in the HTBasic language and are called keywords. For example, PRINT is a BASIC keyword. Keywords can be used as variable names, if they are entered partly in uppercase and partly in lowercase. Every statement except an assignment (if LET is omitted) or a subprogram CALL (if CALL is omitted) must begin with a keyword. A keyword cannot have embedded spaces. Keywords are printed in uppercase in program listings.

Keywords must be delimited by a space or some other legal delimiter and cannot be abbreviated. For example, PRINT USING cannot be entered as PRINTUSING. Neither can PRINT be entered as PRI.


Program Contexts

HTBasic programs can be made up of a collection of program contexts. Contexts are program units that have their own environment, including local variables. There are four types of contexts: the main context, a subprogram context, a user defined function context, and a CSUB context.

By default, all context variables are local in scope. A local variable cannot be changed by another context unless it is passed by reference. It exists temporarily, only while its program context is being executed. If a context is invoked recursively, each invocation of the context has its own set of local variables.

Global variables defined in a COM statement can be accessed from any program context in the HTBasic program that includes the proper COM statement. More information on variables and their scope is presented later in this chapter.


Main Context

The main context includes all of the program lines from the first line up to and including the END statement. This context executes first and may call other subprogram contexts.


Subprogram Contexts

Subprogram contexts are program units that begin with a SUB statement, optionally define parameters, end with a SUBEND statement, can be invoked recursively by other contexts, and can be passed arguments, either by reference or by value. They are similar to procedures and functions in other structured languages and are sometimes referred to as "true" subroutines. Subprogram contexts allow arguments to be passed, local variables to be declared, and global variables to be referenced.


User Defined Function Contexts

A User Defined Function context begins with a DEF statement, optionally defines parameters, ends with a FNEND statement, can be invoked from within an expression by referencing its name, and can be passed arguments, either by reference or by value. When it terminates, it returns a value with a RETURN statement. The expression then continues to evaluate, using the returned value in place of the function reference.


CSUB Contexts

A CSUB is a compiled subprogram created with special tools outside of HTBasic. It is loaded into memory with the LOADSUB statement and removed from memory with the DELSUB statement. It is invoked with a CALL statement. A simple alternative to CSUBs are assembly language routines accessed with special READIO/WRITEIO statements.


Integer Numbers

INTEGER is a numeric data type. INTEGERs are whole numbers (-1, 2, 35) ranging from -32768 to +32767. INTEGERs are stored in two bytes of memory and INTEGER operations are faster than REAL operations.


Real Numbers

REAL is another numeric data type. REAL numbers, also called floating point numbers, are a subset of all rational numbers. The particular subset depends on your computer. Most computers, including the IBM PC, use IEEE Std 754-1985 for Binary Floating point numbers. This gives the REAL data type an approximate range of 1E-308 to 1E+308 and 15 decimal digits of precision. Eight bytes are used to store a REAL number. Both positive and negative numbers are represented. MINREAL and MAXREAL are functions that return the smallest and largest REAL numbers.

Integral numbers too large to be represented by the INTEGER type, numbers expressed with a decimal point, and numbers expressed in scientific notation are stored as REAL numbers. Scientific notation on computers is usually expressed as x.xxxEyyy, meaning x.xxx is multiplied by 10 raised to the yyy power. For example: 3.141E0, 4E-7, -101.1E+2. REAL operations are slower than INTEGER operations and REAL numbers take more memory space to store.


Cautions

Some cautions are in order when using REAL numbers. It is possible to have two different REAL numbers whose 15 digit decimal representations are the same. However, when comparing or subtracting these two numbers that look equal, you will find they are NOT equal. Also, since REAL numbers are only a subset of the rational numbers, some operations produce a result that is not in the set of REAL numbers. If the result is too large in magnitude, it produces an overflow error. If the result is too small, it produces an underflow error. The result may be between two numbers in the REAL set. In this case, an approximation must be used for the actual value. Most of us have witnessed this happening by dividing one by three on a hand-held calculator. Digits that the calculator can not store are just discarded.

Each of these pitfalls is demonstrated in the following program:

10 RAD
20 One = COS(3)*COS(3)+SIN(3)*SIN(3)
30 PRINT One,One-1.0

From trigonometry we know that line 20 should assign the value one to the variable One. And indeed, when One is printed, we see it is "1". However, when the value of One-1.0 is printed, we do not get zero. We get a very small value.


REAL Comparisons

Rather than compare two REAL values for equality, it is often best to compare them for an acceptably small difference. For example, the rest of the program started above:

40 IF ABS(One-1.0) < 1E-15 THEN PRINT "EQUAL ENOUGH"

Alternately, DROUND or PROUND can be used to round the binary representations to match each other:

50 PRINT One,DROUND(One,1)-DROUND(1.0,1)
60 END


FOR Loops

It is not a good idea to use a REAL variable as the loop counter in a FOR loop. Rounding errors tend to accumulate when a REAL variable is used as the loop counter in a FOR loop. For example:

10    FOR X=1 TO -1 STEP -.05
20      PRINT X;TAB(20);ACS(X)
30    NEXT X
40    END

It is expected that this loop would include 0 and -1 among the values printed for X. However, when this example is executed, a small non-zero value is printed in place of 0 and the loop terminates before getting to -1.

INTEGER variables should be used for the loop counter. The number of iterations can then be exactly specified. The REAL values needed in the loop can be generated each iteration from the INTEGER variable. This approach does not allow rounding errors to accumulate. The previous example should be replaced with:

10    INTEGER I
20    FOR I=0 TO 40
30      X=1-I*.05
40      PRINT X;TAB(20);ACS(X)
50    NEXT I
60    END


Definition

The exact subset of rational numbers that can be represented by REAL numbers (on computers using IEEE-754) is the set of all numbers expressible in the form:

(-1)s * 2e * mantissa

where:
s = 0 or 1.
e = any integer between -1022 and +1023.
mantissa = b0 * 2-0 + b1 * 2-1 + ... + b52 * 2-52
b0 = 1
bi = 0 or 1 (for i<>0)


Complex Numbers

COMPLEX is yet another numeric data type. The COMPLEX data type defines a number having two components, like a two-dimensional vector. In a complex number, however, there is a well-defined relationship between the two components of the number. The first component in a complex number is called the real part and the second component is called the imaginary part. A complex number is often written in the form

x + iy,

where x represents the real part of the number and y the imaginary part. X and y are ordinary REAL numbers and have the same range as REAL numbers. The i is defined as the square root of -1.


Strings

A string is another data type. A string is a combination of ASCII characters. These are the letters, numbers, and symbols that you can type on the keyboard. ASCII characters also include control characters such as carriage return, etc. A string also has a current length. The length can be zero, meaning that there are no characters stored in the string, or any size up to a maximum of 32767.


I/O Paths

An I/O path is yet another data type. From mathematics we are familiar with numeric data types. The string type is somewhat harder to understand, but the I/O path type is the most abstract and by far the hardest to understand. An I/O path consists of all of the routing information necessary for the computer to exchange data between your HTBasic program and another entity (such as a printer, data acquisition device, string, file, etc.). Data is assigned to an I/O path variable with the ASSIGN statement. Unlike the other data types, PRINT can not be used to examine the contents of an I/O path variable. However, the contents are used when an OUTPUT, ENTER, or other statement specifies the I/O path variable.


Constants

A constant is a quantity with a fixed value. There are four types of constants: string, COMPLEX, REAL, and INTEGER. COMPLEX, REAL and INTEGER constants are collectively called numeric constants. The following are examples of numeric constants:

Example	Type of Constant
1	- integer constant
1.0	- real constant
2.718281828	- real constant
-20000	- integer constant
+1E+0	- real constant
40000	- real constant (32767 is max integer size)
CMPLX(0,1)	- complex constant


Numeric Constants

Numeric integer constants can also be expressed in octal (base 8) or hexadecimal (base 16). A hexadecimal constant must begin with the characters "&H". An octal constant must begin with the characters "&O" or simply "&". Hexadecimal and octal constants are an extension in HTBasic and are not supported in HP BASIC. The following are examples of hexadecimal and octal constants:

Example	Type of Constant
&H10	hexadecimal constant with decimal value of 16
&O10	octal constant with decimal value of 8
&20	octal constant with decimal value of 16


String Constants

A string constant is a sequence of ASCII characters enclosed in quotation marks. They are also called string literals. A quotation mark may be included in a literal by entering two adjacent quotation mark characters. For example:

100 PRINT "This is a quotation mark >""<"

This will print:

This is a quotation mark >"<


Variables

A variable is an entity with memory and a changeable value. Each variable has a name, a type, a scope, and a value. Array variables remember multiple values. The rules for naming variables, the variable type, the scope of a variable, and array variables are explained in the following paragraphs.

A string or numeric variable can be assigned a value that comes from a constant, another variable, an expression, or a DATA, INPUT, ENTER, or READ statement. An I/O path variable can be assigned using the ASSIGN statement. The type of data must match the variable type.


Variable Names

A variable name can have up to 15 characters. The characters can be alphabetic, numerals, underlines, and characters ranging from CHR$(128) to CHR$(254). The first character may not be a numeral or an underline. The last character of a string variable name must be followed by the dollar sign character, "$". The first character of an I/O path variable name must be the at-sign character, "@".

A variable name can be the same as a keyword if it is entered partly in uppercase and partly in lowercase characters. Variable names are listed with the first character in uppercase and the remaining characters in lowercase. Here are some examples of legal and illegal variable names (and why):

Variable	Explanation
Smile	legal
FOR	illegal, FOR is a keyword
For	legal with mixed case
I	legal
X1	legal
X-7	illegal, minus sign is not allowed
Supercalifragalisticexpealadoeshous	illegal, too long


Variable Types

There are five types of variables:

•  Real
•  Integer
•  Complex
•  String
•  I/O Path

You must indicate the type of each variable in some way. Use the REAL statement to declare real numeric variables. Use the INTEGER statement to declare integer variables and the COMPLEX statement to declare complex variables. If a numeric variable is not declared, it is declared REAL automatically. To turn off automatic declaration of variables, execute CONFIGURE DIM OFF.

HTBasic recognizes a string variable from the dollar sign, "$", following the last character of the string name. The DIM statement is used to set the maximum string length. The length of a string stored in a string variable cannot exceed its DIMensioned length. To dimension a string named S$ with a maximum length of 20, use the following syntax:

DIM S$[20]

If a string is not declared in a DIM statement, it is normally dimensioned automatically to a maximum string length of 18 characters. To turn off automatic declaration of variables, execute CONFIGURE DIM OFF.

An I/O path variable does not have to be declared. HTBasic recognizes it from the at-sign character, "@", preceding the variable name. The ASSIGN statement is used to set up the I/O path variable before a data transfer.


Variable Scope

HTBasic supports variables with two different scopes,  local and global.

All variables not defined in a COM statement are local in scope. The values of local variables are only accessible within the context in which they are defined. All local variables are assigned the value zero when the context begins execution. When the context finishes execution, the values of the local variables are discarded. When a context is called recursively, each invocation of the context is given its own set of local variables. The COMPLEX, REAL, INTEGER, DIM, and ALLOCATE statements are used to declare local variables.

No memory is reserved for ALLOCATEd variables until the ALLOCATE statement is executed. The DEALLOCATE statement releases the memory before the context finishes execution. ALLOCATE is only used for array and string variables

COM variables are global in scope. The values of COM variables are stored in COM blocks that are global in lifetime. A COM block is a set of one or more variables that is held in "common" (i.e. may be shared) among one or more contexts. Each COM block is uniquely identified with a name (although one block is allowed to be nameless). As many COM statements as necessary may be used in a context to fully describe the COM block variables.

To access COM variables, a context must include a COM statement that identifies the COM block and gives the names by which the variables will be known in that context. Thus, each context can give a different name to the same COM variable. COM variables are hidden from all contexts that do not include a COM statement accessing that COM block.

When a new program is brought into memory, the existing COM blocks are compared to the COM blocks defined in the new program. Any COM blocks that exactly match are retained and their data values are available for use by the new program. Any COM blocks that do not match are deleted and the memory used by their data values is released and may be reused by the new program.


Array Variables

A simple variable has one data value. An array is a multi-dimensional ordered set of data values. Each member of the set is called an array element. All the members of the set have the same data type which can be COMPLEX, INTEGER, REAL, or string. An array variable can not have the same name as a simple variable.

The number of dimensions of the array is called the RANK. Arrays may have a RANK from one to six. You can specify both the lower and upper bound of each dimension. If the lower bound is not specified then the current OPTION BASE of the context is used as the lower bound. The default OPTION BASE is zero.


Declaration

Local array variables are declared using the COMPLEX, INTEGER, REAL, and DIM statements. The ALLOCATE statement is used to dynamically declare a local array. The COM statement is used to declare a global array. Normally, all array variables that are not declared will be declared automatically with the default lower bound, an upper bound of 10, and a RANK matching the number of subscripts in the first reference to the array. To disable automatic array declaration, use CONFIGURE DIM OFF.


String Arrays

A string array may be defined where each element of the array is a separate string of the dimensioned length. To dimension a string array named S$ with four elements (assuming the default OPTION BASE 0), each of which can have a maximum length of 20 characters, use the following syntax:

DIM S$(3)[20]


Examples

A few examples follow showing array declarations.

DIM X(3)    ! declares an array of 4 REALs.

This example defines an array with elements numbered 0,1,2,3. If you have set the context OPTION BASE to 1, then it would define an array with elements numbered 1,2,3.

INTEGER A(50:100)   ! declares an array of 51 integers.

This example defines an integer array with 51 elements numbered 50 through 100.

One-dimensional arrays are always referenced by one subscript in parentheses following the array variable. For example, A(2) refers to the third element. Two-dimensional arrays are referenced by two subscripts, where the first subscript refers to the row, and the second subscript refers to the column. For example, A(1,2) refers to the second row, the third column. An element of an array can be used wherever a simple variable of the same type can be used.

Once an array variable is declared, it can be assigned elements via:

•  [LET] statement	•  MAT statement
•  INPUT statement	•  ENTER statement
•  READ statement.

To use the [LET] statement to assign values to array elements, you must first DIMension the array.

100 DIM A(1:2,1:2)

This statement sets the working size of A to two rows and two columns, and enough memory space is reserved to store four numeric values; one value for each element.

Next, you assign a numeric constant to each element. Each element must be assigned a value using subscripts on the array variable as follows:

110 A(1,1) = 5
120 A(1,2) = 6
130 A(2,1) = 7
140 A(2,2) = 8

The MAT statement can be used to assign an entire array. For example:

100 MAT A = (1)  ! all elements in A are set to 1

Another way to assign values to the elements of an array is to use the INPUT statement:

100 DIM A(1:2,1:2)
110 INPUT A(*)

When these statements are executed, the variable A is dimensioned to a 2 by 2 matrix. The INPUT statement then reads the keyboard entries into the elements of the array A. The elements are input in row major order. For example, the following input assigns the same values as the lines 110 to 140 above:

5,6,7,8

Each entry must be separated by a comma or by pressing the RETURN key. The input request prompt is displayed again and again until an entry is made for each element in the array.

The READ statement can also be used to assign values to the elements in an array. For example:

100 DIM A(1:2,1:2)
110 DATA 5,6,7,8
120 READ A(*)

When these statements are executed, the numeric constants in the DATA statement are assigned to array A in row major order.

You can also use a FOR/NEXT loop to assign values in some other order or starting point. For example:

100 DIM Beta(1:99)
110 FOR J = 40 TO 50
120   ENTER @Path;Beta(J)
130 NEXT J


Program Flow Control
Chapter 4
Program Flow Control

This chapter describes the program execution states, conditional branching statements, looping statements, subroutines, subprogram contexts, user defined functions, event and error handling statements, and the EXECUTE statement.


Program Execution

An HTBasic program is started by pressing the RUN key or entering the RUN statement directly from the keyboard. A prerun pass is made over each context before the program begins execution. The program then executes normally until it encounters an END, PAUSE, or STOP statement. While running, a message is displayed near the bottom right of the screen to indicate that a program is running.

The WAIT statement can be used to temporarily suspend the execution of the next program line for a specified number of seconds.


The Paused State

Program execution can be halted by pressing the PAUSE key, executing a PAUSE statement in the program, or entering the PAUSE statement. While PAUSEd, the values of variables in the current context can be printed or changed and the program can be examined with the LIST or EDIT statements. The program can be restarted by pressing the CONTINUE key, or entering the CONT statement. A program error will also PAUSE the program, as will the CLR I/O key if pressed during an I/O statement. Changing a program line while PAUSEd, will change the state of the computer to a stopped state.


The Stopped State

The program can be forced to halt at some point other than the END statement by pressing the STOP key, executing a STOP statement in the program, or entering the STOP statement. After the program halts, the values of the variables in the main context can be examined and changed. However, changing any program line will cause the current values of the local variables to be discarded.

Pressing the RESET key will also stop a running program, but also resets the HTBasic environment. The STOP, PAUSE, and CLR I/O keys are preferred.


Returning to the Operating System

Control is returned to the operating system by executing the QUIT statement from the keyboard or in a program line. HTBasic performs an orderly shutdown by closing all files and then it returns to the operating system command processor.


Branching

Branching allows program execution to jump to a statement other than the next statement. The GOTO statement allows you to make an unconditional transfer to another program line in the same context, but its use is discouraged in favor of structured flow control statements. The GOTO can specify a line number or label. For example:

GOTO 120
GOTO Fix_up


Conditional Statements

Conditional statements allow you to make decisions. The most common conditional statement is the IF...THEN statement. It allows program execution to change depending on the result of the specified expression.

The simple form of the IF...THEN statement allows either program execution to jump to another statement in the same context or a single program statement to be executed. Here are some simple IF...THEN examples:

IF A$="Q" THEN 700              ! conditional transfer
IF A$="N" THEN PRINT "No !"     ! single statement

The block IF...THEN statement allows any number of statements to be conditionally executed. If the expression evaluates true, all of the statements enclosed by the IF...THEN statement down to the END IF or ELSE statement are executed. The optional ELSE statement can be used within a block IF...THEN statement to enclose any number of statements. If the condition evaluates false, all of the statements enclosed by the ELSE statement down to the END IF are executed. A block IF...THEN statement can be nested inside another block IF...THEN statement.

100  IF Xlimit>Upper THEN
110    PRINT "The current setting is ";Xlimit
120    READ Xlimit
130    PRINT "The new setting is ";Xlimit
140  ELSE
150    Xlimit = Xlimit+1
160  END IF

In this example line 100 starts a "block" IF structure. Lines 110, 120, and 130 are all executed if Xlimit>Upper is true; otherwise, line 150 is executed.


ON...GOTO Statement

The ON...GOTO statement provides a multi-way branch depending on the value of the specified expression. Control is transferred to one of the program lines, in the same context, selected from the list of line numbers or labels whose position in the list matches the value of the expression. If the value is 1 then the first line number is used, if the value is 2 then the second line number is used, etc. If the value is less than one or is larger than the number of line numbers or labels specified, an error is generated.

ON J GOTO 300,400,500,600 ! value of J determines GOTO


ON...GOSUB Statement

The ON...GOSUB statement is like the ON...GOTO statement except that program control is sent to one of the subroutines, in the same context, specified in the line number or label list. When the subroutine executes the RETURN statement, control returns to the line following the ON...GOSUB statement. For more information on the GOSUB statement and subroutines, see the subroutine explanation later in this chapter.

ON X GOSUB 300,400,500,600 ! value of X determines GOSUB


SELECT and CASE Statements

The SELECT statement begins a block which executes alternative statement blocks based on the value of the expression specified. Just as a block IF...THEN ends with an END IF statement, a SELECT block ends with an END SELECT statement. Within the SELECT block, CASE statements enclose alternative statement blocks. SELECT statements can be nested. This means that one SELECT statement can be nested inside another.

When the SELECT statement is executed, the SELECT expression is first evaluated and then the resulting value is tested against the list of values in each CASE statement until either a CASE statement matches the SELECT value or until an optional CASE ELSE statement is encountered. The enclosed program statements up to the next CASE or END SELECT statement are then executed. Control is then transferred to the line following the END SELECT statement. If no CASE statement matches and no CASE ELSE statement is encountered, control is immediately transferred to the line following the END SELECT statement.

The CASE statement specifies a list of expressions each separated by a comma. The type of the expressions, either numeric or string, must match the type of the SELECT expression. Each expression may specify either a match value, a relational operator (<, <=, =, >=, >, or <>) followed by a match value, or a range specified by a lower and an upper match value. Each expression is evaluated one at a time and the resulting value is tested against the SELECT expression result. If any expression matches, then the CASE statement matches and the statements up to the next CASE or END SELECT statement are executed.

Because the first matching CASE statement will be executed regardless of the later CASE statements, care must be exercised in selecting the order of the CASE statements.

The following example illustrates the use of the SELECT and CASE statements:

100  INPUT "What is your age? ",Age
110  SELECT Age
120  CASE <1,>100
130    PRINT "Do you expect me to believe that?"
140    GOTO 100
150  CASE <12
160    Price = 2
170  CASE 12 TO 59
180    Price = 6
190  CASE 60
200    PRINT "Special Rate Tonight:"
210    Price = 4.5
220  CASE ELSE
230    Price = 5
240  END SELECT
250  PRINT USING """Movie price is $"",D.2D ";Price
260  END


Loops

A program loop allows the repeated execution of a set of statements. There are four types of program loops: FOR/NEXT, LOOP/END LOOP, REPEAT/UNTIL, and WHILE/END WHILE.


FOR Loops

FOR/NEXT loops let you specify how many times to repeat a block of statements. You should use FOR loops when the block will be executed a fixed number of times. It is legal to use a GOTO statement to jump out of the FOR loop, but this violates the philosophy that the block is to be executed a fixed number of times. You may specify an optional STEP value by which the variable is to be incremented or decremented. If no STEP value is specified, it defaults to one. The value of the variable is tested against the termination value before the loop is executed the first time. If it is beyond the termination value, control transfers to the line following the NEXT statement.

The NEXT statement adds the STEP value to the value of the variable and then tests it against the termination value. If it is not beyond the termination value, control transfers to the line following the FOR statement. If it is beyond the termination value, the loop terminates and the value of the variable is left as it is. An example FOR/NEXT loop follows:

10  FOR J=50 TO 100 STEP 2
20    READ A(J)
30  NEXT J


Other Loop Types

The other types of program  loops repeatedly execute their statement block until the exit condition is satisfied. Depending on the loop statements used, the test for loop termination can be made at the beginning, the end, or at any place inside the loop. A loop can be nested inside another loop. The following examples illustrate the three types of loop termination:

Start of loop     End of loop       Middle of loop
100 WHILE X<>4    100 REPEAT        100 LOOP
. . .             . . .             . . .
. . .             . . .             150 EXIT IF X=4
. . .             . . .             . . .
200 END WHILE     200 UNTIL X=4     200 END LOOP


Subroutines

A subroutine is accessed by a GOSUB statement and consists of one or more HTBasic statements whose last statement is a RETURN. When the GOSUB statement is encountered, the current line number is saved and control is transferred to the specified line number or line label in the same context. Execution continues until the RETURN statement is encountered, at that time control is returned to the line following the GOSUB statement. A subroutine example follows.

100  GOSUB 200
. . .
200  X = Y*45/Z
210  RETURN

This subroutine can be called from many places in the program to save having to duplicate the subroutine statements many times.


Program Contexts

HTBasic programs are made up of a collection of contexts. Contexts are program units that have their own environment, including local variables. There are four types of contexts: the main context, a subprogram context, a user defined function context, and a CSUB context.

By default, all context variables are local. A local variable cannot be changed by another context unless it is passed by reference. It exists temporarily, only while its program context is being executed. If a context is invoked recursively, each invocation of the context has its own set of local variables.

Global variables defined in a COM statement can be accessed from any program context in the HTBasic program that includes the proper COM statement. Chapter 3, "Language Elements," contains more information on variables.


Main Context

The main context includes all of the program lines from the first line up to and including the END statement. This context executes first and may call other subprogram contexts.


Subprogram Contexts

Subprogram contexts are program units that begin with a SUB statement, optionally define parameters, end with an SUBEND statement, can be invoked recursively by other contexts, and can be passed arguments. They are similar to procedures and functions in other structured languages and are sometimes referred to as "true" subroutines. Subprogram contexts allow arguments to be passed, local variables to be declared, and global variables to be referenced. Subprograms are called with the CALL statement, or with a FN reference in a numeric expression. Arguments can be passed either by reference or by value.

Note:  The term "parameters" refers to the list of variables in a SUB (or DEF FN) statement. The term "arguments" refers to the corresponding list  in a CALL statement (or FN function).

Pass by reference means a subprogram is told the location of a variable. Therefore, altering the parameter is the same as altering the original variable. In effect, the parameter name becomes a synonym for the original variable name. I/O path variables, numeric and string variables, and array elements are all passed by reference.

Pass by value means a subprogram is told the value of a variable, but not where the original variable is stored. The subprogram can change the value of the parameter, but since the subprogram doesn't know where the original variable is stored, it can not modify it. Expressions, constants, and literals are passed by value. Place parentheses around a variable or array element to pass it by value instead of by reference.

A subprogram context example follows:

100  CALL Do_it(X,4,(Y))
. . .
199  END
. . .
200  SUB Do_it(D1,D2,D3)
210    D1=D1+1
220    D2=D2+1
230    D3=D3+1
. . .
300  SUBEND

Line 100 will cause X to be incremented because it is passed by reference. The 4 is passed by value and Do_it is not told where the 4 came from. The same is true for Y; it will not be incremented.


Subprogram Pointers

A subprogram is typically referenced by explicitly naming it. For example, to call a subprogram named Robert, use the statement

CALL Robert

In several statements, it is also possible to name the subprogram using a string expression. This allows the name of the subprogram to change dynamically as the program runs. The subprogram must be specified with the initial character in uppercase, and subsequent characters in lowercase. For example:

CALL A$

If A$="Robert", the statement will call the subprogram named Robert. If A$ has some other value, the statement will call some other subprogram. The string expression specifying the subprogram name is called a "subprogram pointer" because it "points" to the subprogram rather than explicitly naming it. As the expression changes, the pointer points to different subprograms. Subprogram pointers are allowed in CALL, INMEM, LOADSUB, DELSUB, and XREF statements.

This example shows one use for subprogram pointers:

10  IF Case=1 THEN
20    Method$="Real"
30  ELSE
40    Method$="Complex"
50  END IF
60  IF NOT INMEM(Method$) THEN LOADSUB Method$
70  CALL Method$ WITH(X,Y,Z)
80  DELSUB Method$
90  END


User Defined Function Contexts

A User Defined Function context begins with a DEF FN statement, optionally defines parameters, ends with a FNEND statement, can be invoked from within an expression by referencing its name, and can be passed arguments, either by reference or by value. When it terminates, it returns a value with a RETURN statement. The expression then continues to evaluate, using the returned value in place of the function reference.

The defined function can return either a numeric value or a string value. If it returns a string value, the function name must end with a dollar sign ($) and the RETURN statement must specify a string value. For example:

100  PRINT "Today is: ";FNToday$
110  END
. . .
120  DEF FNToday$
130    A$=DATE$(TIMEDATE)
140    RETURN A$[1,6]
150  FNEND


CSUB Contexts

A CSUB context is a compiled subprogram created with special tools outside of HTBasic. It is loaded into memory with the LOADSUB statement and removed from memory with the DELSUB statement. It is invoked with a CALL statement. A simple alternative to CSUBs are assembly language routines accessed with the special READIO/WRITEIO statements.


Interrupting Program Flow

Normal program flow can be interrupted by any of several events: CYCLE, DELAY, END, ERROR, INTR, KBD, KEY, KNOB, SIGNAL, TIME, and TIMEOUT.

The ON statement defines the action to take when an event occurs. It defines the event type, the servicing priority, the type of branch used, and the service routine. Event branching occurs between program lines and can be a GOTO, a GOSUB, a CALL, or a RECOVER.

The destination of a GOTO or GOSUB must be a program line in the present context. If the event occurs while execution is in a different context, the event is logged and execution continues. When control returns to the proper context, the branch then takes place.

The destination of a RECOVER must also be a program line in the present context. However, if the event occurs while execution is in a different context, then SUBEXITs are automatically performed until control is returned to the proper context.

The destination of a CALL must be a SUB context that defines no parameters. When the event occurs, a CALL is performed to the SUB context. Upon exit of the SUB context, control is returned to the context that was executing when the event occurred.


Priority

The event priority designates which events can interrupt other event service routines. An event can only interrupt a lower priority routine. If the present SYSTEM PRIORITY is equal to or larger than the priority of an event handling routine, the event is logged and serviced later when the SYSTEM PRIORITY allows it. The main context begins running at a priority of 0, allowing any event to be serviced. The event priority may be specified from 1 to 15 and if it is not specified, defaults to 1.

If the branch type is a CALL or GOSUB, then when the event is serviced the SYSTEM PRIORITY is changed to the specified event priority. When a SUBEXIT or RETURN is executed, the SYSTEM PRIORITY is restored to its value before the event was serviced. If the branch type is a GOTO, the system priority is not changed. If the branch type is a RECOVER, the automatic SUBEXITs restore the SYSTEM PRIORITY to the value it was when the defining context invoked another context.

The ON END, ERROR, and TIMEOUT events form a special class and each indicates an error condition. The priority of the END and TIMEOUT events is 15 so that no normal event can interrupt their service routines. However, they can interrupt service routines for any event, including another END or TIMEOUT event. The priority of an ERROR event is 17. It cannot be set or changed with the SYSTEM PRIORITY statement.


Global and Local Aspects

The ON/OFF state of an event and the key labels are local to each context. The initial state is inherited from the invoking context. When returning from a context, the state is restored to what it was when the context was invoked. CYCLE interval, DELAY time, KBD ALL modifier, KNOB interval, TIME value, and TIMEOUT values are global. Changing them in a context overrides their values specified in previous contexts. Consider this example:

10    ON KEY 1 LABEL "Done" RECOVER 40
20    CALL S
30 Spin: GOTO Spin
40    END
50    SUB S
60      ON KEY 2 LABEL "More" GOSUB More
70      SUBEXIT
80 More: PRINT "More"
90      RETURN
100   SUBEND

When Spin is reached, only KEY 1 will be defined. This is because events are local to the defining context and the contexts called from that context. When the SUBEXIT statement is executed in line 70, the ON KEY 2 in line 60 is discarded.


Disabling Events

The DISABLE statement disables all defined event branches except END, ERROR, and TIMEOUT. While disabled, the first event of each type that occurs is logged. When event branching is re-enabled with the ENABLE statement, all logged events are serviced in the order of their event priorities.

An event branch definition is removed with an OFF statement specifying the matching event type. This may include an I/O path name, an interface select code, a key number, or a signal number.

10   A$=FNInkey$
20   PRINT LEN(A$),A$
30   END
40   DEF FNInkey$       ! Input one key without echo,
50     ON KBD GOTO 80   !  and a 10 second timeout
60     ON DELAY 10 GOTO 90
70     GOTO 70
80     RETURN KBD$
90     RETURN ""
100  FNEND

This example illustrates use of two ON event statements to implement an Inkey$ function. The function, as defined in the example, inputs one keystroke. If no key is pressed within ten seconds then the null string is returned.


Error Handling

HTBasic includes many features for handling execution errors. A user written subroutine or subprogram, called an error handler, can be executed when an error occurs.


Defining an Error Handler

The ON ERROR statement defines the action to take when an error occurs. It defines the type of branch used and the service routine. The branch type can be a GOTO, a GOSUB, a CALL, or a RECOVER. If no error handler is defined, the error message is displayed and the program PAUSEs. For example:

ON ERROR GOSUB 200
ON ERROR GOTO Fix_it
ON ERROR RECOVER 1510
ON ERROR CALL Handler

An ON ERROR statement is canceled by an OFF ERROR statement and is not disabled by the DISABLE statement.

The destination of a GOTO or GOSUB must be a program line in the present context. If the error occurs while execution is in a different context, the ON ERROR definition is ignored, the error message is displayed, and the program is PAUSEd.

The destination of a RECOVER must also be a program line in the present context. However, if the error occurs while execution is in a different context, then SUBEXITs are automatically performed until control is returned to the proper context.

The destination of a CALL must be a SUB context that defines no parameters. When the error occurs, a CALL is performed to the SUB context.

An ON ERROR can interrupt any event service routine since it has a priority of 17 which is higher than any event branch. It cannot be set or changed with the SYSTEM PRIORITY statement. If another ERROR occurs while the system is at this priority (a "double fault"), then the program is PAUSEd even though an ON ERROR definition is in effect.


The Error Handler Routine

If the branch type is a CALL or GOSUB, then when the error is serviced the system priority is changed to 17. When a SUBEXIT or RETURN is executed, the system priority is restored to its value before the error was serviced. If the branch type is a GOTO, the system priority is not changed. If the branch type is a RECOVER, the automatic SUBEXITs restore the system priority to the value it was when the defining context invoked another context.

If an error occurs in the service routine of an ON ERROR GOSUB or CALL, it is reported to the user and the program is PAUSEd. If an error occurs in the service routine of an ON ERROR GOTO or RECOVER, an infinite loop between the error line and the error routine can result.

If there is not enough memory to run the service routine, the original error is reported to the user and the program is PAUSEd.

There are several error indicator functions that can be used by an error handler routine for decision making. The value of the error number (ERRN) and the line number where the error occurred (ERRLN) are updated when an error occurs. If no error has occurred since start-up or SCRATCH A, then a zero is returned. The ERRL function returns a one if ERRLN is equal to the specified line and a zero otherwise. The specified line must be in the current context. The ERRL function is not keyboard executable. The ERRN, ERRLN, and ERRL functions may be used in IF statements to direct program flow in error handler routines.

The ERRM$ function returns the line number (ERRLN), error number (ERRN), and the associated error message string. The null string is returned if no error has been generated since start-up, LOAD, GET, SCRATCH, or CLEAR ERROR.

Errors that occur in connection with background TRANSFER statements are not reported until the associated I/O path variable is accessed. In this case ERRLN is the number of the program line referencing the I/O path, not the TRANSFER statement. Also, ERRN is not updated.

The CLEAR ERROR statement resets ERRL, ERRLN, ERRM$, and ERRN to their default start-up values.

Error handler subroutines ending with RETURN and subprograms ending with SUBEND or SUBEXIT re-execute the line in error. If the error handler does not correct the cause of the error, the error will occur again, causing an infinite loop until the error is corrected. Subroutines ending with ERROR RETURN and subprograms ending with ERROR SUBEXIT do not re-execute the line in error. These statements return to the line following the line that caused the error. For example:

100  ON ERROR GOSUB 500
. . .
. . .
500  INPUT "Value too Large. Try again: ",N
510  ERROR RETURN

During program debugging it is helpful to be able to generate an error just as if it were generated by a running program. The CAUSE ERROR statement allows you to do this. When the statement is executed, it is as though the error specified actually occurred and the normal error functions: ERRL, ERRLN, ERRM$, and ERRN are updated. CAUSE ERROR is also useful in debugging error handlers.


EXECUTE Statement

The EXECUTE statement executes an operating system command or user program. This powerful command allows you to control and intermix the execution of other user programs with your HTBasic program.

The default command interpreter for your operating system is invoked and given the command specified for execution.  For example:

EXECUTE "foobar"

executes the "foobar" operating system command or program. When the command has completed, control is returned to HTBasic. If the command argument is not specified, the default command interpreter is invoked, you are given a prompt, and you may issue one or more commands. You must terminate the command interpreter to return to HTBasic. From DOS, Windows, or NT, type "EXIT". From most UNIX shells, type "exit".

After the command has completed execution, if the WAIT OFF option is not specified, the message "Hit any key to continue" will be displayed and HTBasic waits until you press any keyboard key. If the WAIT OFF option is specified, control immediately returns to the next HTBasic statement.

If the SAVE ALPHA OFF option is not specified, the screen is cleared before the command is executed and the screen is restored after the command has finished. If the SAVE ALPHA OFF option is specified, the screen is not cleared or restored. Messages written to the screen will write over the current screen. You can, however, redirect the output messages to a file and use the WAIT OFF option to prevent writing over the screen. Changes made to the display hardware can leave HTBasic confused. For example, if the EXECUTEd program changes the color map, HTBasic does not know the change has occurred and will continue using the new color map, assuming the HTBasic map is in place.

If the RETURN option is specified, the executed program's termination error value is returned in the numeric variable. Under DOS, NT, or UNIX this is the command interpreter's termination value.

When control is returned to HTBasic, an attempt is made to service any events that occurred while the command interpreter had control. Depending on your operating system, some events may be lost or ignored during this time period.

When operating under a window system, the WAIT OFF and SAVE ALPHA OFF options are ignored. Some examples of statements with options are:

EXECUTE "DIR"; WAIT OFF
EXECUTE "draw"; WAIT OFF, SAVE ALPHA OFF


DOS Version Usage Notes

The COMSPEC environment variable must be set correctly to use EXECUTE. It is used to locate the command interpreter.

You should use the -MINREAL and -MAXREAL switches on CFIG386 (which are explained in the Installing and Using manual) to set aside real memory for the EXECUTE statement. As shipped, the -MINREAL switch is set to 4096 16-byte paragraphs (64 kilobytes). This is enough for COMMAND.COM or small programs, but must be increased for larger programs. There is no easy way to determine the value to use, however there is a straight-forward way: Try larger and larger values until you find one that will work. The size of the .EXE file is a rough indicator of the minimum amount of memory required by a program.


Windows Version Usage Notes

Under NT, CMD is the command interpreter used if no command is specified. To execute a built-in command like "DIR", use "cmd /c DIR". An extension of .EXE is assumed for the command; to execute a .BAT, .CMD or .COM file, include the extension. Under Windows, no command interpreter is available and only other Windows programs can be executed.


UNIX Usage Notes

The shell specified in the SHELL environment variable is used to spawn the command. If no SHELL variable exists, "/bin/sh" is used.


Mathematics
Chapter 5
Mathematics

This chapter describes the mathematical capabilities of HTBasic. Numeric, string, and matrix expressions are made up of operands and operators. Operands can be variables, constants, or the results of expressions. Operators can be infix operators like + and -, built-in functions like COS and EXP, or user defined functions. This chapter also describes automatic data type conversions, execution precedence, and the matrix inversion function.


Numeric Expressions

A numeric expression is defined as any legal combination of operands and operators joined together in such a way that the expression as a whole can be reduced to a numeric value. The following syntax diagram defines the legal combination of operands and operators. Precedence rules place additional constraints that are explained later in this chapter.

numeric-expression =
{ + | - | NOT } numeric-expression |
( numeric-expression ) |
numeric-expression operator numeric-expression |
numeric-constant |
numeric-name |
numeric-array-element |
numeric-function [ ( param [,param...] ) ] |
FN function-name [ ( param [,param...] ) ] |
string-expression compare-operator string-expression

where:
operator = + | - | * | / | DIV | MOD | MODULO | ^ |
AND | OR | EXOR | compare-operator
compare-operator = <> | = | < | > | <= | >=
numeric-function = a function, like COS, which returns
a numeric value.
param = legal parameters for numeric functions and user
defined functions are explained in the Reference
Manual.


String Expressions

A string expression is any legal combination of operands and operators joined together in such a way that the expression as a whole can be reduced to a string value. The following syntax diagram defines the legal combination of operands and operators. Additionally, precedence rules should be kept in mind.

string-expression =
( string-expression ) |
string-expression & string-expression |
"string-literal" |
string-name |
string-array-element |
sub-string |
string-function [ ( param [,param...] ) ] |
FN function-name$ [ ( param [,param...] ) ]

where:
string-function = CHR$ | COMMAND$ | DATE$ | DVAL$ |
ENVIRON$ | ERRM$ | IVAL$ | KBD$ | LWC$ | REV$ |
RPT$ | SYSTEM$ |TIME$ | TRIM$ | UPC$ | VAL$
param = legal parameters for string functions and user
defined functions are explained in the Reference
Manual.


Matrix Expressions

A matrix expression is any legal combination of operands and operators joined together in such a way that the expression as a whole can be reduced to a matrix value. The following syntax diagram defines the legal combination of operands and operators.

MAT string-array$ = string-array$ | (string-expression)
MAT sub-array[$] = sub-array[$]
MAT numeric-array = numeric-array [operator numeric-array]
MAT numeric-array = (numeric-expression) [operator numeric-array]
MAT numeric-array = numeric-array operator (numeric-expression)
MAT matrix = matrix-function [ ( matrix [,matrix] ) ]

where:
operator = + | - | . | / | < | <= | = | <> | >= | > | *
sub-array = array-name( { * | lower-bound:upper-bound | subscript }... )
matrix-function = RSUM | CSUM | INV | TRN | IDN |
REAL | IMAG | ARG | ABS | CONJG | CMPLX
param = legal parameters for matrix functions are explained
in the Reference Manual.


Operands

An operand is defined as that which an operator operates on. For example, in the equation:

A*PI+4/N

the operands are A, PI, 4, and N, while "*", "+", and "/" are the operators. Operands can be strings, I/O paths, complex, real or integer numbers, arrays or array elements. They can be in the form of constants, variables, array elements, or in some cases, entire arrays.


Operators

An explanation of operators that begin with a letter of the alphabet can be found by looking up the name of the operator in the Reference Manual. The following charts list all of the operators, grouping them by category.


Arithmetic

The arithmetic operators provide the standard arithmetic operations as well as the INTEGER division, remainder, and modulo operators.

Operator	Meaning	Example	Result
+	Addition (dyadic)	3+4	7
+	Positive (monadic)	+4	4
-	Subtraction (dyadic)	3-4	-1
-	Negation (monadic)	-3	-3
*	Multiplication	3*4	12
/	Division	3/4	0.75
^	Exponentiation	3^4	81
DIV	Integer Division	4 DIV 3	1
MOD	Remainder	4 MOD 3	1
MODULO	Modulo	4 MODULO 3	1

Several of these operations can generate errors. The following table outlines the possible errors. In general, and whenever possible, the error numbers returned by HTBasic are the same as those returned by HP BASIC. But in some instances the operating system or environment in which HTBasic runs makes it impossible or impractical to return the same number.

Math	Cause of
Operation	Error	Example
Integer +-* DIV	Result too big	32760+32760
DIV	Divide by zero	1 DIV 0
Real +-*/	Result too big	1E200*1E200
Real +-*/	Result too small	1E-200*1E-200
/	Divide by zero	1/0
MOD/MODULO	MOD by 0	1 MOD 0
A^B	Result too big	1E200^1E200
A^B	A<0 and B non-integer	(-2)^6.5
A^B	A=0 and B<0	0^(-1)


Binary

Binary functions perform bit-wise operations on integer numeric values. They may be used to manipulate bits or to perform conditional operations based on their logical result.

Operator	Meaning	Example	Result
BINAND	Bit-wise "AND"	BINAND(3,4)	0
BINCMP	Bit-wise complement	BINCMP(5)	-6
BINEOR	Bit-wise Exclusive Or	BINEOR(3,5)	6
BINEQV	Bit-wise Equivalence	BINEQV(3,5)	-7
BINIMP	Bit-wise Implication	BINIMP(3,5)	-3
BINIOR	Bit-wise "OR"	BINIOR(3,4)	7
BIT	Bit-wise test	BIT(4,2)	1
ROTATE	Bit-wise rotation	ROTATE(3,-4)	48
SHIFT	Bit-wise logical shift	SHIFT(3,-4)	48


Conversions

Conversion functions change an operand from one data type to another. Numeric/string conversions can operate either on ASCII character values (i.e. CHR$(65)) or string representations of numbers (i.e. "65").

Operator	Meaning	Example	Result
CINT	Real to integer	CINT(16.0)	16
CMPLX	Real/integer to complex	CMPLX(2,1)	2+i
CHR$	Numeric to ASCII string	CHR$(65)	"A"
DVAL	Base N to base 10 (32 bit)	DVAL("A",16)	10
DVAL$	Base 10 to base N (32 bit)	DVAL$(11,16)	"B"
&H	Hexadecimal constant	&H10	16
IVAL	Base N to base 10 (16 bit)	IVAL("A",16)	10
IVAL$	Base 10 to base N (16 bit)	IVAL$(11,16)	"B"
NUM	ASCII character to numeric	NUM("A")	65
&O	Octal constant	&O20	16
REAL	Integer/complex to real	REAL(16)	16.0
VAL	String to numeric	VAL("65")	65
VAL$	Numeric to string	VAL$(65)	"65"


Date/Time

Date and time functions read the system time and convert time values in seconds to the familiar human readable forms and vice versa.

Operator	Meaning	Example	Result
DATE	String to seconds	DATE
("1 JAN 1980")	2.11182336E+11
DATE$	Seconds to string	DATE$
(2.11182336E+11)	"1 JAN 1980"
TIME	String to seconds	TIME("01:00:00")	3600
TIME$	Seconds to string	TIME$
(2.11182336E+11)	"00:00:00"
TIMEDATE	Present time/date	TIMEDATE	seconds


Environment

Environment functions return information about the HTBasic environment. The SYSTEM$ function, particularly, provides a wealth of information and is explained in detail later in this chapter.

Operator	Meaning	Example	Result
CHRX	Character cell width	CHRX	8
CHRY	Character cell height	CHRY	14
COMMAND$	Command line	COMMAND$	"-O -Z 2"
CRT	Display ISC	CRT	1
ENVIRON$	Environment variable	ENVIRON$
("PATH")	"C:\;C:\DOS"
FRE	Available Memory	FRE	300000
KBD	Keyboard ISC	KBD	2
MAXREAL	Largest REAL number	MAXREAL	1.798E+308
MINREAL	Smallest REAL number	MINREAL	2.225E-308
NPAR	Number of parameters	NPAR	0
PRT	Printer device selector	PRT	10
RATIO	Graphic screen ratio	RATIO	1.48
SYSTEM$	System information	SYSTEM$
("MSI")	"C:\"


Error

Error functions give information about the latest error that occurred. This information is useful in an error handling routine established by ON ERROR.

Operator	Meaning	Example	Result
ERRL	Test for error line	ERRL(100)	0
ERRLN	Line number	ERRN	10
ERRM$	Error Message	ERRM$	"ERROR 31 IN "...
ERRN	Error Number	ERRN	31


I/O Functions

I/O functions complement the regular I/O statements by providing additional information about I/O operations, devices, and paths.

Operator	Meaning	Example	Result
KBD$	ON KBD, keyboard buffer	KBD$	"A"
KNOBX	ON KNOB, x movement	KNOBX	217
KNOBY	ON KNOB, y movement	KNOBY	-45
PPOLL	Parallel poll on IEEE-488	PPOLL(7)	8
READIO	Read hardware register	READIO(9,0)	7
SC	Select Code in I/O path	SC(@Io)	10
SPOLL	Serial poll on IEEE-488	SPOLL(701)	0
STATUS	Read interface register	STATUS(CRT,1)	1


Logical

Logical operators can be used on integer or real numbers. The two values are first converted to logical (TRUE=1, FALSE=0) values, the operation is done, and the result is converted to an integer. When converting numbers to logical values, zero is converted to FALSE and non-zero is converted to TRUE. When converting the result to an integer, FALSE is converted to a zero, and TRUE is converted to a one.

Operator	Meaning	Example	Result
AND	Logical "and"	2 AND 3	1
EXOR	Logical "exclusive or"	2 EXOR 3	0
OR	Logical "or"	1 OR 0	1
NOT	Logical "not"	NOT 1	0


Relational

Relational operators can be used on numbers or strings. Relational operators can be used in assignment statements, IF statements, and any other place a numeric expression is legal. For example:

10 X = 4*(Y>Z)+J*(A=B AND R<T)

Relational operators may be used on strings to compare the LEXICAL ORDER of the two strings. By default, ASCII values are used to determine relative order. "A" is less than "B". If two strings of different length are the same up to the end of the shorter string, then the shorter string is less than the longer string. For example, "ABCDE" < "ABCDEF". The LEXICAL ORDER IS statement affects the relational ordering of strings.

Operator	Meaning	Example	Result
<	Less than	3<4	1
<=	Less than or equal	3<=4	1
=	Equals	"3"="4"	0
>=	Greater than or equal	3>=4	0
>	Greater than	"3">"4"	0
<>	Not equal	3<>4	1


String Functions

As you have seen, many other operators already described also have string operands or string results. The functions presented here are especially useful for operations with strings. The examples in the following table assume that A$ has the value "HOTDOG".

Operator	Meaning	Example	Result
&	Concatenation	"HOT"&"DOG"	"HOTDOG"
[s]	Sub-string, start	A$[4]	"DOG"
[s,e]	Sub-string, start, end	A$[1,3]	"HOT"
[s;l]	Sub-string, start, length	A$[2;4]	"OTDO"
COMMAND$	Command line	COMMAND$	"-O -Z 2"
CVT$	Converts alphabets	CVT$(X$,Y$)
ENVIRON$	Environment variable	ENVIRON$
("PATH")	"C:\;C:\DOS"
FBYTE	Test for First byte	FBYTE(X$)	0 or 1
LEN	Present length	LEN("AB")	2
LWC$	Lowercase	LWC$("AB")	"ab"
MAXLEN	Dimensioned length	MAXLEN(A$)	18
POS	Position of a sub-string	POS("AB","B")	2
REV$	Reverse	REV$("AB")	"BA"
RPT$	Repeat	RPT$("AB",3)	"ABABAB"
SBYTE	Test for Second byte	SBYTE(X$)	0 or 1
TRIM$	Trim lead/trailing space	TRIM$(" A B ")	"A B"
UPC$	Uppercase	UPC$("ab")	"AB"

A substring defines a portion of a string variable or string array element. The capability of specifying a sub-string of a string variable or string array element is quite powerful. This capability replaces the RIGHT$, LEFT$, MID$, REP$, and SEG$ functions of other BASICs. A sub-string is selected by specifying a starting position within the string value, and optionally, either the length of the sub-string or the ending position within the string value. If only the starting position is specified, the rest of the string value from that point on is used for the sub-string. String positions are one-based, i.e., the first character of a string is in position one.


Transcendental and Trigonometric

The standard transcendental and trigonometric functions are provided along with the ability to specify degree or radian operations. Many other less common functions are available at extra cost. Contact TransEra for information.

Function	Meaning
ACS	Returns the arc cosine of an expression
ASN	Returns the arc sine of an expression
ATN	Returns the arc tangent of an expression
ATN2	Returns the angle to a point
COS	Returns the cosine of an expression
DEG	Statement to set degree mode for trig functions
EXP	Return the exponential of an expression
LGT	Computes common (base 10) logarithms
LOG	Computes natural (base e) logarithms
PI	Returns the numeric value 3.14159...
RAD	Statement to set radian mode for trig functions
SIN	Returns the sine of an expression
SQR	(SQRT) Returns the square root of an expression
TAN	Returns the tangent of an expression


Other Functions

The other functions provide number manipulation for the sign, the fractional or integral parts, rounds to specific decimal places, finds the largest or the smallest value, and generates pseudo-random numbers.

Operator	Functionality
ABS	Absolute value of an expression
CINT	Convert to Integer
DROUND	The number rounded to specified number of digits
FIX	Discard fractional part of a number
FRACT	Fractional part of a number
INT	Greatest integer part of a real number
MIN	Smallest number from list of values and arrays
MAX	Largest number from list of values and arrays
PROUND	The number rounded to the specified decimal place
RES	Result of last live keyboard expression
RND	Random number
SGN	Arithmetic sign of an expression

Notice the differences among CINT, FIX, and INT. CINT converts a REAL value to an INTEGER by substituting the closest INTEGER to the value. FIX returns the closest integral value between the REAL value and zero. INT returns the closest integral value between the REAL value and negative infinity. Also, CINT actually changes the type from REAL to INTEGER while INT and FIX return integral results, but the type is not changed. The following table helps illustrate the differences:

x	CINT(x)	FIX(x)	INT(x)
2.6	3	2.0	2.0
2.2	2	2.0	2.0
-2.2	-2	-2.0	-3.0
-2.6	-3	-2.0	-3.0


User Defined Functions

The DEF FNfunction statement defines a subprogram function context. This function is executed whenever the function name is referenced in a numeric or string expression. You can define as many functions in this way as you wish. Chapter 4, "Program Flow," introduces subprogram contexts and explains how to define and pass arguments to them.


Automatic Conversions

Conversions from REAL to INTEGER and from INTEGER to REAL are done automatically in HTBasic. Basic operations are done in INTEGER math if both operands are INTEGER. Otherwise, REAL math is used. For example:

INTEGER J         ! J is now an integer type variable
X = 1.234         ! X is a real number (by default)
J = X             ! The real value of X is converted to
                  ! integer and assigned to J.
X = J             ! This time conversion is from integer to real
X = 1.0           ! This is faster than X=1 (no convert required)
X = 1             ! This requires a convert to real
X = PI DIV 2.0*10 ! X will equal ten.

The last example above is kind of tricky. The first operation to take place will be INTEGER division. The INTEGER division operation will convert PI to an INTEGER 3 and 2.0 to INTEGER 2. 3 DIV 2 equals INTEGER 1. The multiply will be an INTEGER multiply because 1 and 10 are both INTEGERs. 1*10 equals INTEGER 10, which is converted to REAL 10.0 to be stored in the REAL variable, X.

The same concepts are extended in versions of HTBasic with COMPLEX support. If one operand is COMPLEX, the other is automatically converted to COMPLEX if needed. In cases where a real number is required, a complex number will automatically be converted to a real number by discarding the imaginary portion. In cases where an integer number is required, a complex number will cause an error. In this situation, use the REAL function to force the real part of the complex number to be used.

Conversions may take a noticeable amount of time if many iterations occur. They should, therefore, be avoided whenever speed is a priority.


Execution Precedence

Mathematical precedence describes the order in which operators in an expression are evaluated. Some inexpensive calculators execute each operation as it is entered. If you are familiar with this type of calculator, you may be confused by the concept of precedence.	For example, the correct answer to the formula:

1+2*3+4

is 11, not 13.	This is because multiplication (2*3) has a higher precedence than addition (1+2). If the two operators are on the same row in the precedence chart, the operations occur in left to right order (i.e. 1+2-3+4).

HP BASIC (and HTBasic) has an odd quirk in its definition of precedence that you should be aware of. Most computer languages place all monadic operators (operators that operate on one operand) at a higher precedence than dyadic operators (operators that operate on two operands). However, HP BASIC (and HTBasic) place monadic + and - below some of the dyadic operators. The following is one example of an expression that will evaluate differently because of this:

-4^0.5

With HTBasic, this is equivalent to -(4^0.5) which is equal to -2. With most other computer languages, this is equivalent to (-4)^0.5 which is an illegal operation.

Precedence	Operators/Functions
1	Parentheses () and sub-strings []
2	Functions: built in and user defined.
3	Exponentiation Operator ^
4	Multiplicative Operators *,/,DIV,MODULO,MOD
5	Monadic + and -
6	Dyadic + and -
7	String Concatenation &
8	Relational Operators =,<>,<,>,<=,>=
9	Monadic Logical Operator NOT
10	Logical Operator AND
11	Logical Operators OR and EXOR


Matrix Operators

One of the powerful features of HTBasic is its ability to do operations on complete arrays without the use of loops. This means that programs will run much faster. Many operators that can operate on two simple variables can operate on arrays. Array/array operations or array/scalar (simple variable) operations can be done. Portions or entire arrays can be transferred to another array or a portion of another array. For example:

100 DIM X(10),Y(10),Z(10)
110 MAT Y=(1)          ! defines every element of the array
120 MAT X=Y*(5)        ! array/scalar operation
130 MAT Z=X+Y          ! array/array operation
140 MAT Z(2:3)=Z(9:10) ! sub-array assignment

The operators + - . / < <= = >= > <> require that the operand arrays have the same RANK and that each dimension has the same SIZE. The result array will be REDIMed if needed. However, the usual rules for REDIM apply and if the array cannot be redimensioned, an error is returned. Each of these operators work on the array element by element. The "." operator does an element by element multiply.

The "*" operator performs classical matrix multiplication. The definition of matrix multiplication is given in the following BASIC SUB:

10   SUB Matmpy(A(*),B(*),C(*)) ! Equivalent to MAT C=A*B
20     OPTION BASE 1
30     INTEGER I,J,K,M,N,R
40     M=SIZE(A,1)
50     N=SIZE(A,2)
60     K=SIZE(B,2)
70     IF N<>SIZE(B,1) THEN CAUSE ERROR 16
80     REDIM C(M,K)
90     FOR I=1 TO M
100      FOR J=1 TO K
110        Sum=0
120        FOR R=1 TO N
130          Sum=Sum+A(I,R)*B(R,J)
140        NEXT R
150        C(I,J)=Sum
160      NEXT J
170    NEXT I
180  SUBEND


Matrix Operators with Matrix Result

Besides applying these simple operators to arrays, operators specially designed for arrays can be used:

Operator	Functionality
CSUM	Returns the sum of each column of a 2D array in a vector.
IDN	The identity matrix (1's along diagonal, 0's elsewhere).
INV	Sets one array to the inverse of another.
REORDER	Reorders the elements of an array.
RSUM	Returns the sum up each row of a 2D array in a vector.
SEARCH	Searches for elements in an array.
SORT	Sorts arrays in ascending or descending order.
TRN	Transposes a matrix (rows to columns, columns to rows).


Matrix Operators with Scalar Result

The following operators take a matrix operand and return a scalar result.

Operator	Functionality
BASE	Returns the lowest legal subscript for a dimension.
DET	Returns the determinant of a matrix.
DOT	Dot, or inner product of two vectors.
MAX	Returns largest element of an array and/or scalars.
MIN	Returns smallest element of an array and/or scalars.
RANK	Number of dimensions in a matrix.
SIZE	Upper bound - lower bound + 1 of a dimension.
SUM	Adds up all the elements in an array.


Matrix Sub-array Assignments

Sub-array assignments (sometimes called array slices) require that the number of ranges specified in the source match the number of ranges specified in the destination. If a complete array is specified, the number of ranges equals the rank of the array. In corresponding ranges of the source and destination, the number of elements must be the same. The following examples will help you visualize these rules:

10 DIM X(1:3),Y(1:10)
20 DIM D(3,4,5),S(4,2,5)
30 MAT X=Y(2:4)           ! One range, three elements
40 MAT D(3,*,*)=S(*,2,*)  ! Range 1 has 5 elements, 2 has 6
50 MAT Y(1:6)=S(0,0,*)    ! One range, 6 elements


Matrix Searching

The MAT SEARCH statement searches a numeric or string array for certain conditions. The array can be searched for the following:

•  The location of first element that is less than, greater than, equal to, or not equal to a given value
•  A count of the number of locations that are less than, etc. a given value
•  The location of the maximum or minimum value in the array
•  The value which is the maximum or minimum value in the array

The syntax for MAT SEARCH is:

MAT SEARCH numeric-array [num-key], rule; return [,start]
MAT SEARCH string-array$ [str-key], rule; return [,start]

where:
num-key = [search-subscripts] [DES]
str-key = [search-subscripts [sub-string]] [DES]
search-subscripts = ( {subscript|*} [,...] )
The '*' must appear once.
rule =
[#]LOC ([relational] value) |
LOC MAX |
LOC MIN |
MIN |
MAX
relational = < | <= | = | <> | => | >
return = variable-name
start = numeric-expression
value = string-or-numeric-expression

The keyword DES specifies descending search order. The optional start value specifies the starting subscript. If not specified, searching begins with the first element for ascending searches and the last element for DEScending searches. The meaning of the search rule is:

Operator	Functionality
LOC	Subscript of first element satisfying operator
#LOC	Count the number of elements satisfying operator
LOC MAX	Subscript of maximum value
LOC MIN	Subscript of minimum value
MAX	Find and return the maximum value
MIN	Find and return the minimum value


Matrix Inversion

One of the more complex matrix functions is the INV function used to calculate the inverse of a matrix. Several precautions are in order when using the INV function. The inverse of a matrix A is defined to be that matrix B, such that

AB = BA = I

where I  is the identity matrix. For any matrix A, there is no guarantee that a matrix B exists such that the above relationship can be satisfied. When this is the case, A is called a singular matrix and has a determinant value of zero.

This leads to the first caution to observe when using computer methods for matrix inversion. After using the INV() function to find the inverse of a matrix, the DET function should be tested to determine whether the matrix was singular or non-singular. The determinant of a matrix is a by-product of the computer's inversion algorithm. When the INV function is used, the determinant of that matrix is assigned to the DET function. In the case of a non-singular matrix, it is therefore faster to do the inversion first and then check the DET function. The example below shows both methods.

110 ! The fast way
120 MAT B=INV(A)
130 IF NOT DET THEN PRINT "A is singular"
140 !
150 ! The slow way
160 !
170 IF NOT DET(A) THEN PRINT "A is singular"
180 MAT B=INV(A)

No error is generated when a singular matrix is inverted, but the values assigned to the result matrix are meaningless. You should therefore check the determinant value when doing a matrix inversion.

The second caution is related to the first. When the determinant of a matrix is very near zero, compared to the other elements of the matrix, then the inexact arithmetic used by a computer causes errors in the calculation of the inverse. The closer to zero, the more error is introduced into the result. To test for this condition, multiply the original matrix and its inverse together and compare the result to the identity matrix. If the difference is greater than what is acceptable for your application, then you will not be able to use BASIC to invert that matrix.

The following example illustrates a matrix whose determinant is small compared to the elements of the matrix.

10   REM SMALLDET.BAS
20   DATA 100,200,100.000000000001,200
30   DIM A(1,1),B(1,1),Ab(1,1)
40   READ A(*)
50   MAT B=INV(A)
60   MAT Ab=A*B
70 D2x2: IMAGE K,/,2(2(SD.15DE,2X),/)
80   PRINT USING D2x2;"A=",A(*)
90   PRINT USING D2x2;"B=",B(*)
100  PRINT USING D2x2;"Ab=",Ab(*)
110  PRINT "DET = ";DET
120  END

The output from this program is shown below. Although the product AB is not exactly the identity matrix, it is close enough for many applications.

A=
+1.000000000000000E+02  +2.000000000000000E+02
+1.000000000000010E+02  +2.000000000000000E+02

B=
-1.005267773966630E+12  +1.005267773966630E+12
+5.026338869833190E+11  -5.026338869833140E+11

Ab=
+9.956054687500000E-01  +5.371093750000000E-03
-4.394531250000000E-03  +1.005371093750000E+00

DET = -1.98951966013E-10


Complex Operators

Several operators and statements have been extended to work with complex numbers in addition to real and integer numbers. Also, several operators and statements have been added to work with complex numbers. Automatic conversion rules have also been extended to handle cases where complex and real arguments are mixed. See "Automatic Conversions" earlier in this chapter.


Extended Statements and Operators

Operator	Functionality
+ - * /	Operate on complex numbers
= <>	Operate on complex numbers
ABS	Return absolute value (magnitude or modulus)
ATN	Return arctangent of complex number
COS	Return cosine of complex number
ALLOCATE	COMPLEX can be specified
COM	COMPLEX can be specified
DATA	Use rectangular form separated by comma
DISP	Display in rectangular form separated by space
DEF	COMPLEX can be specified
ENTER	Enter in rectangular form separated by non-numeric
EXP	Return "e" raised to complex power
IMAGE	Treat complex like two REALs
INPUT	Input in rectangular form
LGT	Return base 10 log of complex number
LOG	Return natural log of complex number
MAT	ABS, ARG, CMPLX, CONJG, IMAG, REAL
MAT REORDER	Reorder complex arrays
MAT SEARCH	Search complex arrays
OUTPUT	Output in rectangular form separated by comma
PRINT	Print in rectangular form separated by space
READ	Read in rectangular form

Operator	Functionality
SIN	Return sine of complex number
SQR	Return square root of complex number
SUB	COMPLEX can be specified
TAN	Return tangent of complex number

Notice that only two of the relational operators, <> and =, are extended for complex numbers. The other relational operators depend on the linear ordering of the data type. In other words, all REAL or INTEGER numbers could be laid out on a number line and, of any two different numbers, one would be closer to positive infinity than the other. Since linear ordering is not defined for the complex data type, the <, >, <=, and >= operators are also not defined.


Added Statements and Operators

Operator	Functionality
ACSH	Hyperbolic arccosine of complex or real
ARG	Argument (angle) of complex number in polar form
ASNH	Hyperbolic arcsine of complex or real
ATNH	Hyperbolic arctangent of complex or real
CMPLX	Combine two REALs into a complex
COMPLEX	Declare complex variables
CONJG	Conjugate of complex
COSH	Hyperbolic cosine of complex or real
IMAG	Return imaginary part of complex number
REAL	Return real part of complex number
SINH	Hyperbolic sine of complex or real
TANH	Hyperbolic tangent of complex or real


SYSTEM$

SYSTEM$ returns system status and configuration information. The following sections explain what information can be read. The information returned depends on which of the following strings is specified in the SYSTEM$ command. Examples:

M=VAL(SYSTEM$("AVAILABLE MEMORY"))
PRINT "VERSION "&SYSTEM$("VERSION:HTBasic")


AVAILABLE MEMORY

Returns the available memory in bytes. In most cases the FRE function is easier to use. The amount of available memory when HTBasic is started can be specified with a command line switch. See FRE.


CRT ID

Returns a 12 character CRT identification string. A space in a position indicates that capability is not present.

Bytes	Meaning
1	always "6".
2	always ":".
3-5	CRT width, for example " 80".
6	"H" if at least one display enhancement is supported,
 i.e. inverse, blink, underline. Not all CRTs support
all enhancements.
7	"C" if colors are available in at least one screen mode.
8	"G" if graphics are available.
9	"B" if the display is bit-mapped.
10-12	Maximum value for ALPHA PEN.


DISP LINE

The present content of the display line is returned. This allows you to write subroutines that temporarily save off the display line content, DISP something else, and then restore the display line.


DUMP DEVICE IS

Returns a string specifying the current DUMP DEVICE.


GRAPHICS INPUT IS

Returns a string specifying the current GRAPHICS INPUT device.


KBD LINE

Returns a string whose content is the same as the current keyboard input line.


KEYBOARD LANGUAGE

Returns a string identifying foreign language keyboards. On some computers, it is not possible for HTBasic to know the keyboard type. On these systems "ASCII" is returned regardless of the actual keyboard.


LEXICAL ORDER IS

Returns the current language set by the LEXICAL ORDER IS command. "ASCII" is the default.


MASS MEMORY

Returns a sixteen character string identifying types and numbers of mass storage devices attached. On some computers, this information is not available to HTBasic. On these systems, "0" is returned for each device type. If the number of devices of any type exceeds nine, "*" is returned in that byte position.

Bytes	Meaning
1	number of internal disk drives.
2-4	not assigned.
5	number of initialized EPROM cards (always 0).
6	number of bubble memory cards (always 0).
7-16	not assigned.

For DOS versions, the number of internal disk drives is taken from the "Equipment Determination" BIOS call. For Windows, NT, and UNIX, the value is always 0.


MASS STORAGE IS or MSI

Returns the current device and directory. MSI is an abbreviation for MASS STORAGE IS and returns the same information.


PLOTTER IS

Returns a string specifying the current PLOTTER IS device.


PRINTALL IS

Returns a string specifying the current PRINTALL IS device.


PROCESS ID

Under multitasking operating systems such as UNIX, this call returns the process ID of HTBasic. Under single-tasking operating systems such as DOS, this call always returns "0".


PRINTER IS

Returns a string specifying the current PRINTER IS device.


SERIAL NUMBER

Returns a string containing the serial number. The number is unique for that class of hardware. On a PC, the serial number is an 11 character string read from the ID Module connected to the parallel port. Under SunOS 4.x, the serial number of the computer (the hostid) is returned as an 11 character string. Under HP-UX, the machine identification number is returned. If the serial number can not be found, the string "11111111111" is returned. (This is the same action as the HP Viper Board.)


SYSTEM ID

A string identifying the hardware system is returned. The DOS Versions of HTBasic use the IBM PC System ID byte located at F000:FFFE to determine what seven character string should be returned. The following table gives the responses generated:

ID Byte	Computer	SYSTEM$("SYSTEM ID")
F8	PS/2 Model 80	"PS/2 80"
F9	PC Convertible	"PC Conv"
FA	PS/2 Model 30	"PS/2 30"
FB	PC/XT	"PC/XT  "
FC	PC/AT, PS/2 Models 50/60	"PC/AT  "
FD	PC Jr	"PCjr   "
FE	PC/XT	"PC/XT  "
FF	PC	"PC     "
other	Unknown	"PC     "

Under Windows and NT, three numbers are returned, separated by commas. The first number is the processor type, the second is the number of processors and the third is the machine OEM ID, if it has one.

Under UNIX, HTBasic uses the machine name returned by "uname -m", which may not be seven characters long.


SYSTEM PRIORITY

Returns a string containing the current system priority. Use VAL(SYSTEM$("SYSTEM PRIORITY")) to retrieve the priority as a numeric value.


TIMEZONE IS

Under operating systems like DOS, which store the local time in the real time clock, this call always returns "0". Under operating systems like UNIX, which store Greenwich Mean Time in the real time clock, this call returns the number of seconds difference between your local time and GMT. Negative values represent timezones west of Greenwich.


TRIG MODE

Returns the current trigonometric mode, "DEG" for degrees and "RAD" for radians.


VERSION:BASIC

Returns a string containing the HP BASIC version number emulated, i.e. "5.1", "6.2", etc.


VERSION:HTB

Returns a string containing HTBasic version information. This is the same information printed on the first line of the CRT when HTBasic starts.


VERSION:OS

Returns a string containing operating system revision information. Under DOS, the string is of the form "x.yy DOS" where x is the major revision and yy is the minor revision.

Under Windows, the string is of the form "x.yy Windows/DOS" and under NT it is "x.yy Windows NT". X is the major revision and yy is the minor revision.

Under UNIX, the string is of the form "x y", where x is the revision number returned by "uname -r" (which may not begin with a numeric character) and y is the system name returned by "uname -s". For example, "4.1.1 SunOS". Use the UNIX command "man uname" for more information about uname.


VERSION:bin-name

Returns a string containing the version number of the binary named. Replace bin-name with the name of the binary of interest. LIST BIN can be used to see the version numbers for all loaded binaries.


WILDCARDS

Returns "OFF:" if wildcarding is turned off. Under UNIX, if wildcarding is turned on, this function returns "UX:e", where "e" is the escape character. Under DOS, Windows, and NT, this function always returns "ON:". See WILDCARDS in the Reference Manual.


WINDOW SYSTEM

Returns "Console" under most versions of HTBasic. Under some versions it returns the name of the current screen driver. See PLOTTER IS for an explanation of screen drivers.


Graphics
Chapter 6
Graphics

HTBasic contains an extensive assortment of powerful graphic statements. These allow you to use convenient data units, not just pixels, in defining your graphic display. Your data units are automatically scaled to the correct graphic device units. Also, the same program can use a variety of graphic devices (screen, plotter, or printer) without having to modify the graphics statements.

This chapter coordinates information and concepts relating to the HTBasic graphics system. The graphics statements are introduced beginning with the simple statements and progressing to the more complex ones. Several examples are given to help you see as well as understand the concepts that are presented. Please try the examples on your computer.

Because of the large number of HTBasic graphic statements, not all of the options and syntax details are explained in this chapter. For more detailed syntax information or attribute values refer to the statement descriptions in the Reference Manual as you read through this chapter.


Simple Graphics Statements

The simplest graphics statements initialize the graphics system, clear the GRAPHICS and ALPHA screens, and control the pen movement to draw graphic lines. The HTBasic statements used to perform these functions as well as the graphic coordinate system used by HTBasic are described in the following paragraphs.


GINIT Statement

The GINIT statement resets all the graphics parameters to their default values. It terminates any graphics input device or active plotter. If graphics output is directed to a file, the file is closed. It also causes the graphics screen to be cleared before the next graphics statement is executed. If you enter GINIT followed by a DRAW 50,50 statement the following occurs: GINIT resets all graphics parameters to their default values. Before the DRAW command is executed the screen is cleared and then a line is be drawn from the origin to 50,50.


GCLEAR and CLS Statements

The GCLEAR statement erases both the GRAPHIC and the ALPHA screen, then re-displays the ALPHA screen. To clear the ALPHA screen, use the CLEAR SCREEN or CLS commands.


Graphics Coordinate System

The HTBasic graphics system is based on the Cartesian coordinate system. This system uses a pair of values to define the location of each point in a graph relative to the origin at (0,0). The first value specifies how far the point is to the right of the origin and the second value specifies how far the point is above the origin. Negative values specify locations to the left of or below the origin. The horizontal line passing through the origin is called the X axis and a vertical line passing through the origin is called the Y axis.

The default origin, (0,0), is the lower left corner of the display screen. The default top vertical value is 100. The default right horizontal value depends upon the display aspect ratio and is usually about 148.

Let us now examine the simple graphic statements used to control the pen movement to generate graphic lines. They are the MOVE, DRAW, PLOT, and PENUP statements.


MOVE and DRAW Statements

The MOVE statement raises the pen and then moves it to the specified position. The DRAW statement draws a line from the current position to the specified position using the current line type and pen number. MOVE always lifts the pen before moving to the specified position. DRAW always begins with the pen down, draws to the new position, and ends with the pen down. Let's now try an example:

10 GINIT
20 DRAW 100,100
30 MOVE 100,0
40 DRAW 0,100
50 END

This example draws a large X on the graphics screen. If you were not already in GRAPHICS mode the display mode is switched to GRAPHICS mode and any ALPHA text is repainted on the graphics screen. The first DRAW statement lowers the pen at the current position (0,0 because of the GINIT statement) and draws a line to position 100,100. The MOVE statement raises the pen and moves it to position 100,0. The next DRAW statement lowers the pen at the current position 100,0 and draws a line to position 0,100.


PLOT Statement

The PLOT statement, like the MOVE and DRAW statements, moves the pen to the specified location and optionally specifies when the pen is to be raised or lowered. For example:

PLOT 45,80,-1

first lowers the pen and then moves it to location 45,80. If the optional pen-control value is not specified, the pen is lowered after a move. The pen-control value is interpreted as follows.

Pen Control	Action
positive even #, & zero	pen is raised after a move
positive odd #	pen is lowered after a move
negative odd #	pen is lowered before a move
negative even #	pen is raised before a move

Negative values cause the pen action to occur before the move and positive values cause the pen action to occur after the move. Even numbers cause the pen to be raised, and odd numbers cause the pen to be lowered.

A two or three column numeric array can be used to supply the coordinate and optional pen-control values. If a three-column array is specified, the third-column specifies the pen-control value to use for each row. It can also specify many other operations as covered later in this chapter. The earlier MOVE/DRAW example could have used the PLOT statement as follows:

10 GINIT
20 DATA 100,100,-1, 100,0,-2, 0,100,-1
30 INTEGER A(2,2)
40 READ A(*)
50 PLOT A(*)
60 END

This example draws the same large X on the screen using the PLOT statement and a three-column data array to specify the coordinates and the pen-control values.


PENUP Statement

The PENUP statement raises the pen without changing its position. This is used with plotters when you don't want the pen to "bleed" onto the paper while it is not moving.


User Defined Graphic Units

Up to this point we have been working in the default graphic units. We now turn our attention to specifying the graphic units that are most convenient for the display of your data values.

The computer screen is, in effect, our viewport into the entire cartesian coordinate system. Only the graphic points that fall within the viewport will be displayed; all other points are eliminated. Lines that cross through the viewport are clipped at the boundaries. The portion of the screen that is to be used to display graphics is specified by the VIEWPORT statement. The CLIP statement allows you to specify clipping boundaries that are different than the VIEWPORT. The SHOW and WINDOW statements specify which portion of the cartesian coordinate system is mapped into the VIEWPORT for display.


VIEWPORT Statement

The VIEWPORT statement specifies the area of the screen or graphic device to be used for graphics output and it also sets the soft-clip boundary limits to match the viewport bounds. The VIEWPORT parameters control the proportions, size, and position of the drawing surface. All graphic output is automatically scaled to fit this drawing surface. The coordinate of the left edge must be less than that of the right edge and the bottom edge must be less than the top edge. It is specified as follows:

VIEWPORT Left,Right,Bottom,Top

The VIEWPORT boundary parameters are defined in GDUs (Graphic Display Units). GDUs are units that describe the physical bounds of the display area on the graphic output device. By definition, Graphic Display Units are 1/100 of the shorter axis of a plotting device. A unit in the X direction and a unit in the Y direction are the same length. The RATIO function returns the ratio of the X to Y physical bounds for the PLOTTER IS device and can be used to determine the VIEWPORT soft-clip limits.

If the ratio is less than 1, the X axis is 100 GDUs and the Y axis is (100*RATIO) GDUs long; if the ratio is greater than 1, the Y axis is 100 GDUs and the X axis is (100*RATIO) GDUs long. The VIEWPORT soft-clip limits should not exceed the physical bounds of the device. By default the left limit is zero, the right limit is the X axis physical bound, the bottom limit is zero, and the top limit is the Y axis physical bound.

Changing the VIEWPORT does not affect any currently displayed graphics, only graphics that you subsequently generate.

As mentioned any graphic points that fall outside the VIEWPORT are eliminated and any lines that cross through the VIEWPORT are clipped at the boundaries. These boundaries are called the soft-clip bounds. They must be within the device physical limits or the hard-clip bounds.

The following program outputs the same graphics information to three different VIEWPORTs.

10  GINIT
20  VIEWPORT 10,50,60,85        !Viewport #1
30  GOSUB 100
40  VIEWPORT 60,100,60,85       !Viewport #2
50  GOSUB 100
60  VIEWPORT 10,100,30,50       !Viewport #3
70  GOSUB 100
80  STOP
90  !
100 FRAME
110 AXES 10,10,20,20,2,3
120 RETURN
130 END

The first and second viewports are exactly the same size, they are just located at different sections of the screen. The third viewport stretches the X axis and squishes the Y axis, causing the image to be distorted.


CLIP Statement

The CLIP statement allows you to specify new soft-clip limits without changing the current VIEWPORT values and it enables and disables clipping at the soft-clip boundaries. If no CLIP statement is executed, the soft-clip boundaries are the most recently defined by either a VIEWPORT (soft-clip) or PLOTTER IS (hard-clip) statement.

Use the CLIP ON statement prior to any graphic statements that might generate points outside the soft-clip area. If CLIP ON is active, a theoretical move or draw to any point that is outside the defined soft-clip area is executed. If a draw is executed, then only that portion of the vector which lies inside the soft-clip area is drawn. The portion of the vector that lies outside the soft-clip area is clipped (chopped off) at the edge of the soft-clip boundary. If both the current logical position and the specified position are outside the soft-clip area the logical position is updated but no physical pen movement is made.

Execute a CLIP OFF statement to disable clipping so you may add labels, comments, graphics or any other plotting that is to be done outside the soft-clip area. When clipping is disabled, clipping will only be done on the physical device limits. If the soft-clip limits are smaller than the physical device boundaries, then CLIP OFF allows you to generate graphic coordinates that fall outside the soft-clip limits but inside the device physical boundaries. For example:

10 GINIT
20 VIEWPORT 10,100,50,80
30 FRAME
40 AXES 3,3,0,0,2,3
50 CLIP OFF
60 MOVE 15,-25
70 LABEL "LABEL OUTSIDE CLIP AREA"
80 END

The default WINDOW setting (0,RATIO*100,0,100) is mapped into the new VIEWPORT area of (10,100,50,80). We enclose the VIEWPORT area with the FRAME statement so you can see the area. Clipping is turned off and we move outside the soft-clip area to (15,-25) and draw a line.

The difference between the CLIP and VIEWPORT statements can be confusing. The following examples should help you see the different effects these commands have on graphics scaling and clipping.

Example A                         Example B
10 GINIT                        10 GINIT
20 VIEWPORT 20,60,20,60         20 CLIP 20,60,20,60
25 WINDOW 0,148,0,100           25 WINDOW 0,148,0,100
30 FRAME                        30 FRAME
40 MOVE 10,10                   40 MOVE 10,10
50 DRAW 80,70                   50 DRAW 80,70
60 CLIP OFF                     60 CLIP OFF
70 DRAW 90,70                   70 DRAW 90,70
80 END                          80 END

In example A, the WINDOW values (0,148,0,100) are mapped into the new VIEWPORT area (20,60,20,60). All the MOVE and DRAW X,Y values are within the window and thus no clipping is done. In example B, the VIEWPORT remains the entire screen and the WINDOW values are again mapped into the VIEWPORT area, but the CLIP command specifies that any line outside the range of the clipping area (20,60,20,60) is not displayed. After CLIP OFF, the final DRAW is displayed.

You specify the bounds and the units of your coordinate system with either the SHOW or the WINDOW statement. They both specify a rectangular area with dimensions as large or as small as you like. The units that you thus define are known as  User Defined Units (UDUs) and are used by all the graphic drawing statements. The meaning of each unit is entirely up to you. They can be any units of measure you wish to work with (inches, miles, years, etc.). For example, if you are plotting a sine wave that has a domain of 0 to 2*PI and a range of -1 to +1, you would use these values as the bounds of your coordinate system.


SHOW Statement

The SHOW statement specifies the bounds of the data values to be displayed within the VIEWPORT in isotropic units so that the X and Y units are of equal length. You specify the left, right, bottom, and top coordinate bounds as follows:

SHOW Left,Right,Bottom,Top

The SHOW values are manipulated internally to give you isotropic units in both the X and Y directions. The SHOW statement finds the difference between the X and Y ranges and the smaller range is scaled into the larger, causing the specified area to be centered within the plotting area. For example:

SHOW -100,100,2,10

For a screen with square pixels the calculations would be: an X difference of 200 and Y difference of 8 is found by subtracting the lower bound from the upper. The smaller Y range is scaled into the larger X range. The difference between the X and Y ranges is 192 (200-8), and half of this, 96, is applied to each Y value. The new minimum Y value is -94 (2-96) and the maximum value is 106 (10+96).

For screens that don't have square pixels, the values are automatically adjusted to prevent distortion.


WINDOW Statement

The WINDOW statement specifies the bounds of the data values to be displayed within the VIEWPORT in non-isotropic units where the X and Y units are of different lengths. If not specified, the default WINDOW is equal to the default VIEWPORT setting. It is specified as follows.

WINDOW Left,Right,Bottom,Top

The SHOW and WINDOW statements only differ in how they map data onto the VIEWPORT.

An image can be "mirrored" about the X or Y axis by reversing the order of the limits for each dimension by specifying the larger value before the smaller value. This is true for both the SHOW and WINDOW statements. For example:

SHOW 0,RATIO*100,100,0     !Mirror about Y Axis
WINDOW RATIO*100,0,0,100   !Mirror about X Axis

Please note: You do not have to set the WINDOW bounds to whole units. Set them to the units most convenient for your data. The coordinates are always translated to the units required for the full resolution of your graphic device. Do not think that because your graphic display has a low resolution that this will be carried over to a plotter.


WINDOW and VIEWPORT Effects

We will now use the RECTANGLE statement to see how it is affected by different WINDOW and VIEWPORT values. There are several forms of the RECTANGLE statement. The simplest form specifies the desired width and height and draws only the boarder lines. For example:

10 GINIT
20 MOVE 10,20
30 RECTANGLE 10,10
40 END

draws a small square near the origin. You can change the WINDOW to a smaller range to cause the square to be drawn larger. Add the following statement.

24 WINDOW 0,30,0,30

The VIEWPORT is still the entire screen, but the range of values mapped into the VIEWPORT is now smaller. The WINDOW values are (0,30,0,30) instead of the default (0,Ratio*100,0,100). This creates a larger box when the same RECTANGLE statement is used. Note that the square is now stretched onto the VIEWPORT. This is because the VIEWPORT is not square and the WINDOW was not adjusted to compensate. To get a square on the screen either the VIEWPORT or the WINDOW must be changed. The simplest way is to select a square VIEWPORT by adding the following statement.

22 VIEWPORT 0,100,0,100

Note that this displays the square again, but it is shifted to the left, since the right side of the screen is inaccessible with this VIEWPORT. Try experimenting with different WINDOW and VIEWPORT settings to understand how they interact with each other.


Annotating Charts and Graphs

Now that you know how to specify a convenient coordinate system and its units of measure we turn our attention to the HTBasic statements used to annotate charts and graphs.


AXES and GRID Statements

By including an axis or grid with appropriate tic marks and labels you can make data plots and graphs more readable and meaningful. The AXES and GRID statements make this easy. The AXES statement draws a single X-Y axis across the soft-clip area, while the GRID statement generates grid lines across the entire soft-clip area. They are specified as follows:

AXES [xtic [,ytic [,xorg [,yorg [,xcnt [,ycnt [,size]]]]]]]
GRID [xtic [,ytic [,xorg [,yorg [,xcnt [,ycnt [,size]]]]]]]

where:
x/ytic = tic spacing
x/yorg = origin of axis
x/ycnt = major tic counts
size   = major tic size

The default values for the X and Y tic spacing and the axis or grid location are 0,0,0,0. The X and Y major tic counts specify the number of tic intervals between major tic marks. Their default values are 1 indicating that every tic interval is major. The default major tic length is two graphic display units. The minor tic marks are half the length of the major tic marks.

The AXES statement produces tic marks that are symmetric about the axis and that extend to the soft-clip boundaries. If the X or Y axis is outside the soft-clip area, tic marks are drawn in the soft-clip area. The AXES lines and tic marks are drawn in the current line type and pen number. A major tic is placed at the axis origin.

The GRID statement generates major tic marks lines across the entire soft-clip area. Cross tic marks are generated at the minor tic mark intersections. The grid is drawn with the current line type and pen number. The pen position after a GRID statement is at the axis origin. For example:

10 GINIT
20 AXES 5,5,50,50,2,3
30 DRAW 60,60
40 END

produces an axis with the origin at 50,50. A tic mark is placed every 5 units in both the X and Y direction. In the X direction every second tic mark is twice as big as the others, because it is a major tic. Every third tic mark in the Y direction is a major tic. The DRAW statement shows you the current X,Y location. Now change line 20 to the GRID statement.

20 GRID 5,5,50,50,2,3

The origin of the GRID is at 50,50 just like the AXES. The major tic marks extend across the entire soft-clip area. Where the minor tic marks cross, a small tic is placed. The DRAW statement again shows you the current X,Y location.

To create a fully enclosed box with tic marks along the outside use two AXES statements, one with an intercept in the lower left corner of the screen, and the other in the upper right corner of the screen.


FRAME Statement

The FRAME statement draws a line around the soft-clip area using the current pen and line type. It ends with the pen up and is positioned in the lower left corner of the FRAME.


LABEL Statement

To annotate a graphics image with text the LABEL statement is used. The CSIZE, LDIR, and LORG statements control the graphic text size, direction, and origin, respectively.

The LABEL statement draws graphic text beginning at the current pen position, in the current pen number and line type. Labels are clipped at the soft-clip boundary just like any other graphics. The scaling of the SHOW and WINDOW statements have no effect on the LABEL statement. This keeps them from becoming distorted by the scaling of graphic data.

The LABEL statement is similar to the PRINT statement except that the text is drawn on the graphics screen. See the PRINT statement for an explanation of arrays, numeric and string fields, and numeric and string formats. Also the following control characters have a special meaning when processed by the LABEL statement:

Keystroke	Character	Action
CTRL-H	CHR$(8)	moves pen left one character cell.
CTRL-J	CHR$(10)	moves pen down one character cell.
CTRL-M	CHR$(13)	moves pen left length of completed label.


CSIZE Statement

The CSIZE statement sets the character size (height) and optionally the expansion factor (width/ height) for the text generated by the LABEL statement. For example:

CSIZE 10,.8

Both values are specified in graphic display units. The default character height is five and the default expansion factor is 0.6. These values are in effect at start-up, or when GINIT, or RESET are executed. A negative height or expansion-factor inverts the character in relation to that dimension.


LDIR Statement

The LDIR statement specifies the angle of rotation from the X-axis that the LABEL is drawn. A value of zero specifies drawing along the positive X-axis. Positive values specify a counter-clockwise direction. The current trigonometric mode (RAD or DEG) determines the units for the angle. The default is radians. For example:

LDIR 0.56


LORG Statement

The LORG statement specifies the relative position of the LABEL with respect to the current pen position. Its argument has a range of one through nine. The default LORG origin is one. The values are defined as follows:

Left Values	Middle Values	Right Values
3 - left-top	6 - middle-top	9 - right-top
2 - left-center	5 - middle-center	8 - right-center
1 - left-bottom	4 - middle-bottom	7 - right-bottom

If the LABEL is an odd number of characters, the center of the string is the center of the middle character. The following program demonstrates all 9 LORG values and the effect it has on LABELS.

10 FOR I=1 TO 9
20   GINIT
30   DRAW 50,50
40   LORG I
50   LABEL "LORG ";VAL$(I)
60   WAIT 1
70 NEXT I
80 END


Graphic Attributes

We now cover the concepts relating to, and the statements used to specify the graphic attributes that can be used to modify displays. These are the graphic line types, colors, and writing modes. They are described in the following paragraphs.


LINE TYPE Statement

The LINE TYPE statement sets the style or dash pattern and optionally the repeat length of drawn graphic lines. The repeat factor is the GDU line length before the line pattern is repeated.

The default LINE TYPE is number one, a solid line. Dotted and dashed lines of various types may be specified in a manner similar to this example:

LINE TYPE 5

When the GRAPHIC device is not the screen, the line types are device dependent. The following example demonstrates the screen line types.

10 GINIT
20 FOR T=1 TO 10
30   LINE TYPE T
40   Y = T*10
50   MOVE 10,Y
60   DRAW 90,Y
70 NEXT T
80 END


Color Graphics

HTBasic provides powerful statements for generating color graphic displays. Both the HSL (Hue, Saturation, Lightness) and the RGB (Red, Green, Blue) color definitions can be used to specify a color. If the internal computer display contains a color map the display colors may be specified. An alternate drawing mode and many graphics writing modes allow great flexibility in creating graphic displays. Each of these topics is covered in the following paragraphs.


HSL Color Space

The HSL color space is designed to be intuitive and follows the model of mixing paints. An artist preparing a color for a painting, first selects a hue (pure color pigment). He may then add black or white paint to arrive at the desired color. Adding white serves to wash out the color. In technical terms, we say this affects the saturation of the color. The artist may then adjust the brightness by adding black paint. This affects the amount of light reflected by the pigment. We call this the luminosity.

Saturation ranges from zero (white) to one (pure color - no added white). Luminosity ranges from zero (black) to one (pure color - no added black). Hue ranges from zero to one. The diagram below gives an indication of where several colors occur in that range:


RGB Color Space

The RGB color space is designed to match the way in which our eyes work, and in turn, the way in which television and computer displays are designed. The display has three color guns: Red, Green, and Blue. By specifying a number in the range zero (corresponding to zero intensity) to one (corresponding to maximum intensity) for each of the three guns, you can uniquely define all the colors that can be produced by that display.


Pen Numbers

The graphics color is specified with the PEN statement as shown by this example:

PEN 4

If the current graphic device is the plotter it selects which pen is used to draw the lines. If the current graphic device is the computer system display, the pen number selects the color in which all graphics lines are drawn. Some display systems can operate in more than one graphics mode, and the number of available colors depends on the current graphics mode. In addition the color display can operate in one of two color modes: non-COLOR MAP mode and COLOR MAP mode.

If the display does not have a color map or if the COLOR MAP option is not specified in the PLOTTER IS statement, then the display operates in non-color map mode and the SET PEN statement has no effect. The pen number is translated to an RGB number as shown in the table below and stored in the display buffer. For example, pen number 5 specifies cyan and it is translated to the RGB number 011.

The following table gives the pen number to RGB number assignments. For monochrome displays, only the first two entries apply.

PEN	COLOR	Red	Green	Blue
0	black	0	0	0
1	white	1	1	1
2	red	1	0	0
3	yellow	1	1	0
4	green	0	1	0
5	cyan	0	1	1
6	blue	0	0	1
7	magenta	1	0	1


COLOR MAP Mode

To enable the Color Map mode the COLOR MAP option must be specified in the PLOTTER IS statement. A display with a color map allows any color to be assigned to any pen. The SET PEN statement is used to assign colors to pens. The following table gives the default color to pen assignments.

Pen	Color	Pen	Color
0	black	8	black
1	white	9	olive green
2	red	10	aqua
3	yellow	11	royal blue
4	green	12	maroon
5	cyan	13	brick red
6	blue	14	orange
7	magenta	15	brown


SET PEN Statement

The SET PEN statement defines part or all of the color map. A color may be specified in either the RGB or the HSL color space by using the INTENSITY or the COLOR keywords respectively. You may redefine an individual pen by specifying one HSL or RGB color value or multiple pens by specifying an array. In either case, the pen-number specifies the first entry in the color map to be defined. For example:

SET PEN pen-number COLOR h, s, l
SET PEN pen-number COLOR numeric-array(*)
SET PEN pen-number INTENSITY r, g, b
SET PEN pen-number INTENSITY numeric-array(*)

The pen-number should be in the range 0 to n-1, where n is the number of colors supported by the map. The closest possible color will be used if the computer display cannot display the color you select. This statement is ignored if not in COLOR MAP mode.

Immediate Effect. Any pixels already drawn with the specified pen are changed to the new color. All SET PEN statements take effect immediately upon execution. The effects of all SET PEN statements last until the next SET PEN statement of the same pen, or until GINIT, PLOTTER IS, SEPARATE/MERGE ALPHA, or QUIT. In cases where dithering is used, changing the color map changes the colors available to the dithering process, and changes the colors of areas already drawn with dithering that use that particular pen as part of the dither pattern.

In addition to the PEN and SET PEN statements the GESCAPE statement can affect the graphics color.

EGA Colors. The EGA display adapter card supports four possible level settings for each color gun. This allows each pen to have any of 64 possible colors. The red, green, and blue values are interpreted as follows:

Value	% Level
0 - .09	OFF
.1 - .49	1/3 ON
.5 - .89	2/3 ON
.9 - 1	ON

VGA Colors. The VGA display adapter card supports 64 possible level settings for each color gun. This allows each pen to have any of 262,144 possible colors. The red, green, and blue value range is 0 to 1, where 0 means the color is totally off and 1 means the color is totally on.


GESCAPE Statement

The GESCAPE statement exchanges device-specific information with a graphic device. It is specified as follows:

GESCAPE device-selector, code [,param(*)][;return(*)]

The device selector specifies the graphic device. The code value specifies the type of operation. The param array sends information to the device and the return array receives information from the device. The type, size, and shape of the arrays must be appropriate for the requested operation.

Code	Description
1	returns number of color map entries
2	returns color map values
3	returns hard-clip values
4	sets normal drawing mode
5	sets alternate drawing mode
6	returns graphic display mask
7	sets graphic display mask
100	sets HP PaintJet color palettes for non-COLOR MAP mode
101	sets HP PaintJet color palettes for COLOR MAP mode
102	returns the current VIEWPORT and WINDOW
103	returns the current PEN and AREA PEN assignments
104	sets PLOTTER device specific variables
105	sets GRAPHICS INPUT device specific variables
106	sets DUMP device specific variables


Code 1

Code 1 returns the number of color map entries. The return array must be a one dimensional INTEGER array and have at least one element. The first element is assigned the number of color map entries. The following program shows how to return the number of color map entries.

10 INTEGER A_return(0)
20 GESCAPE CRT,1;A_return(*)
30 PRINT A_return(0)
40 END


Code 2

Code 2 returns color map values. The return array must be a two dimensional REAL array, with at least one row and three columns. The first row contains color information for pen 0, second row for pen 1, etc. If the array does not have enough rows, only part of the color map is returned. If the array has too many rows, only part of the array will be used. The first column contains the information for red, the second for green, and the third for blue. The color information ranges in value from zero to one. Color values are multiples of 1/N, where N is the number of non-black shades available for each color. For the IBM PC EGA and VGA N is 15.

A_return(0,0) - Pen 0 red color map value
A_return(0,1) - Pen 0 green color map value
A_return(0,2) - Pen 0 blue color map value
. . . .	.
. . . .	.
. . . .	.
A_return(15,0) - Pen 15 red color map value
A_return(15,1) - Pen 15 green color map value
A_return(15,2) - Pen 15 blue color map value

The following program shows how to return the color map values.

10 REAL A_return(15,2)
20 GESCAPE CRT,2;A_return(*)
30 PRINT A_return(*)
40 END


Code 3

Code 3 returns the hard-clip values and GSTORE array size. The values are returned in plotter units or pixels. The return array must be a one dimensional INTEGER array and must contain at least four elements. The first four elements of the array are assigned the values, X min, Y min, X max, Y max, respectively. For a CRT, the fifth and sixth elements give the INTEGER array dimensions needed by the GSTORE command to store the screen image.

A_return(0) - X minimum hard clip value
A_return(1) - Y minimum hard clip value
A_return(2) - X maximum hard clip value
A_return(3) - Y maximum hard clip value
A_return(4) - # of rows that GSTORE requires
A_return(5) - # of columns that GSTORE requires

The following program shows how to return the hard-clip & GSTORE values.

10 INTEGER A_return(5)
20 GESCAPE CRT,3;A_return(*)
30 PRINT A_return(*)
40 END


Codes 4 & 5

Codes 4 and 5 change the graphics writing mode. If the code is 4, the drawing mode is set to normal. If 5 is specified, the drawing mode is set to alternate. The graphics writing mode provides a great deal of flexibility in the generation of graphic displays. It defines the method used to modify the pixel color bits. These include clearing, setting, inclusive or, exclusive or, complementing, and anding the color bits with the complement of the current pixel color bits. It is specified by a combination of the drawing mode and the sign of the current pen number.

The writing mode of the pen is specified by the current drawing mode and the sign of the pen number. The following table defines the different writing modes available. P is a positive pen number, X is the present value of a pixel. For Non-color map mode, the value of P is the RGB number, not the pen number.

GESCAPE CRT,4	GESCAPE CRT,5
Statement	Normal	Alternate
PEN P	P	BINIOR(X,P)
AREA PEN P	P	BINIOR(X,P)
PEN 0	BINCMP(X)*	0
AREA PEN 0	0	0
PEN -P	BINAND(X,BINCMP(P))	BINEOR(X,P)
AREA PEN -P	BINAND(X,BINCMP(P))	BINAND(X,BINCMP(P))

*PEN 0 in Normal Drawing Mode will do BINCMP(X) in non-color map mode and 0 in COLOR MAP mode.

GESCAPE codes 4 and 5 are not supported on monochrome graphic displays such as CGA and Hercules (HGC). The following statements show how to change the graphics writing mode.

GESCAPE CRT,4   !Set to Normal Drawing Mode
GESCAPE CRT,5   !Set to Alternate Drawing Mode


Code 6

Code 6 returns the graphics display mask. The return array must be a one dimensional INTEGER array, and must have at least one element. The first element is assigned the value of the graphics write-enable mask. The second element, if present, is assigned the value of the graphics display-enable mask. Each bit in the mask corresponds to one of the bit planes. Bit 0 corresponds to the first plane.

A_return(0) - graphics write enable mask
A_return(1) - graphics display enable mask

The following program shows how to return the graphics enable masks.

10 INTEGER A_return(1)
20 GESCAPE CRT,6;A_return(*)
30 PRINT A_return(*)
40 END


Code 7

Code 7 sets the graphics display mask. This operation is not supported by HTBasic. The param array must be a one dimensional INTEGER array, and must have at least one element. The first element is assigned to the graphics write-enable mask. The second element, if present, is assigned to the graphics display-enable mask.

A_param(0) - graphics write enable mask
A_param(1) - graphics display enable mask

The following program shows how to set the graphics enable masks.

10 INTEGER A_param(1)
20 A_param(0)=8
30 A_param(1)=15
40 GESCAPE CRT,7,A_param(*)
50 END


Codes 100 & 101

Codes 100 and 101 set the HP PaintJet printer color palettes. If the code is 100, the color table used for non-COLOR MAP mode is changed. If 101 is specified, the color table used for COLOR MAP mode is changed. The param array must be a two dimensional INTEGER array. It must have at least one row, and must have three columns. The first row contains color information for pen 0, second row for pen 1, etc. If the array does not have enough rows, or has too many rows, no error is reported. The first column contains the information for red, the second for green, and the third for blue. The color information ranges in value from 1 to 99.

A_param(0,0) - Pen 0 red color palette value
A_param(0,1) - Pen 0 green color palette value
A_param(0,2) - Pen 0 blue color palette value
. . . .	.
. . . .	.
. . . .	.
A_param(15,0) - Pen 15 red color palette value
A_param(15,1) - Pen 15 green color palette value
A_param(15,2) - Pen 15 blue color palette value

The following table gives the default palette settings, used in non-COLOR MAP and COLOR MAP modes. Note that the color values for black and white have been switched. This prevents the printer from printing a large amount of black for the background that is black on the screen.

Non-COLOR MAP Mode	COLOR MAP Mode
Color	Red	Green	Blue	Red	Green	Blue
0	90	88	85	90	88	85
1	4	4	29	4	4	6
2	3	26	22	53	8	14
3	2	22	64	89	83	13
4	53	8	14	3	26	22
5	53	5	25	2	22	64
6	89	83	13	4	4	29
7	4	4	6	53	5	25
8	90	88	85	90	88	85
9	4	4	29	24	27	18
10	3	26	22	5	31	12
11	2	22	64	20	5	29
12	53	8	14	26	5	17
13	53	5	25	64	19	26
14	89	83	13	62	21	13
15	4	4	6	72	41	13

In non-COLOR MAP mode with the screen MERGEd, colors 0 & 9-15 are used when dumping the graphics screen to the printer. If the screen is in SEPARATE mode, colors 0-7 are used. This is because the fourth memory plane is used for text, leaving only three memory planes for graphics. In COLOR MAP mode with the screen MERGEd, color 0-15 are used. If the screen is in SEPARATE mode, colors 0-7 are used.

The color palettes are loaded with the color values starting with palette 0, and continues until either the array is exhausted or palette 15 is reached. The following program shows how to set the color palettes.

10 INTEGER A_param(15,2)
20 DATA 90,88,85,  4,4,6,     53,8,14,   89,83,13
30 DATA 3,26,22,   2,22,64,   4,4,29,    53,5,25
40 DATA 90,88,85,  24,27,18,  5,31,12,   20,5,29
50 DATA 26,5,17,   64,19,26,  62,21,13,  72,41,13
60 READ A_param(*)
70 GESCAPE CRT,101,A_param(*)
80 END


Code 102

Code 102 returns the current VIEWPORT and WINDOW values. The return array should be a two dimensional REAL array with two rows and four columns. The first row is assigned the values of the current window. The second row is assigned the values of the current viewport. For each, the X min, X max, Y min, and Y max values are assigned to the first through fourth columns, respectively. The following program demonstrates this capability:

10  REAL W(1,3)
20  GESCAPE CRT,102;W(*)
30  PRINT "The current window   is";W(0,0),W(0,1),W(0,2),W(0,3)
40  PRINT "The current viewport is";W(1,0),W(1,1),W(1,2),W(1,3)
50  END


Code 103

Code 103 returns the current PEN and AREA PEN assignments. The return array should be a one dimensional INTEGER array with two elements. The first element is assigned the current PEN assignment. The second element is assigned the current AREA PEN assignment. The following program demonstrates this capability:

10  INTEGER P(1)
20  GESCAPE CRT,103;P(*)
30  PRINT "The current      PEN is";P(0)
40  PRINT "The current AREA PEN is";P(1)
50  END


Code 104

Code 104 sets device-specific information. The param array must be a one dimensional INTEGER array. The number of elements required depends on the device driver. Conventionally, it contains two elements. The first element is the operation number and the second element is the value associated with that operation. See the documentation for each driver for information on any GESCAPE 104 operations supported by that driver.

For the HPGL plotter driver, this code is used to enable HPGL/2 capabilities. When HPGL/2 is used, polygons are sent to the plotter for rendering. With many plotting devices, this allows the polygons to be filled. When generating an HPGL file for import into other programs, it is often more desirable for the polygon to import as a single unit, rather than a series of lines. To enable HPGL/2, use the following code. Substitute the ISC for the HPGL plotter in place of Isc in line 40.

10  INTEGER Param(1)
20  Param(0)=1    ! HPGL Operation Number: 1 = HPGL/2 Flag
30  Param(1)=1    ! Value: 1=enable, 0=disable
40  GESCAPE Isc,104,Param(*)


Code 105

Sets device-specific information in the GRAPHICS INPUT IS device. The param array must be a one dimensional INTEGER array. The number of elements required depends on the device driver. The first element is the operation number and the subsequent elements are the values associated with that operation.


Code 106

Sets device-specific information in the DUMP DEVICE IS device. The param array must be a one dimensional INTEGER array. The number of elements required depends on the device driver. The first element is the operation number and the subsequent elements are the values associated with that operation.

For the dump drivers, code 106, operation 1 is used to specify a portion of the screen to dump when DUMP GRAPHICS is executed. The syntax is:

GESCAPE PRT,106,param(*)

The param array must be a one dimensional INTEGER array of five elements. The first element is the operation number. The remaining elements specify the boundary for the DUMP. The boundary is specified in screen units:

param(1) - 1
param(2) - Beginning row
param(3) - Ending row
param(4) - Must be 0
param(5) - Must be 0

The row parameters will revert back to the default of full screen if any of the following conditions occur:

1. Beginning row greater than ending row
2. A new Plotter, Graphics, or Dump driver is loaded
3. A GINIT, SCRATCH A, PLOTTER IS, GRAPHICS INPUT, or CONFIGURE DUMP, commands are executed or a Basic reset is performed.

The CONFIGURE DUMP statement must be executed before the GESCAPE statement. The following program demonstrates this capability:

10   INTEGER A(1:5)
20   DUMP DEVICE IS PRT
30   CONFIGURE DUMP TO "HP-PCL"
40   A(1)=1   ! operation code, always 1
50   A(2)=100 ! begin row, screen units
60   A(3)=300 ! end row, screen units
70   A(4)=0   ! reserved, must be 0
80   A(5)=0   ! reserved, must be 0
90   GESCAPE PRT,106,A(*)
100  FRAME
110  MOVE 0,0
120  DRAW 100,100
130  DUMP GRAPHICS
140  END


Incremental and Relative Graphics

Incremental and relative graphic construction allows you to describe an object or symbol in incremental or relative coordinates, and then position it repeatedly in various locations on the screen (or output device) simply by performing an absolute MOVE to the starting location and then executing the incremental or relative graphics statements. The IMOVE, IDRAW, IPLOT, and RPLOT statements implement incremental and relative graphics.


IMOVE Statement

The IMOVE statement lifts and moves the pen to the position calculated by adding the specified X and Y displacement to the current pen position. After the IMOVE statement is executed, the logical pen position is updated and the pen is left in the up position.


IDRAW Statement

The IDRAW statement lowers the pen and then moves it to the position calculated by adding the specified X and Y displacement to the current pen position. After the IDRAW statement executes, the logical pen position is updated and the pen is left in the down position. IDRAW 0,0 draws a point.


IPLOT Statement

The IPLOT statement moves the pen from its current position by the specified X and Y displacements. Like the PLOT statement discussed previously, you can also specify an optional pen control value or a two- or three-column array.


RPLOT Statement

The RPLOT statement is the same as the IPLOT statement except that it moves the pen relative to the logical pen position. You specify when the pen is to be raised or lowered with the optional pen-control value.

If the arguments of an IMOVE, IDRAW, IPLOT, or RPLOT statement specify a destination point that is outside the soft-clip area, the logical position is set to that point but the pen is not moved. Only the portion of the vector that lies inside the clipping area is plotted. If both the current logical position and the specified position are outside the clip area the logical position is updated but no physical pen movement is made.


Arcs, Circles, and Rectangles

Special purpose graphic statements are used to generate arcs, circles, and rectangles. They are the POLYGON, POLYLINE, and RECTANGLE statements. Each is discussed in the following paragraphs.


POLYGON and POLYLINE Statements

The POLYGON and POLYLINE statements generate variable sided polygons or circles. The pen starts and ends in the same position, and after execution the pen is up. The radius is the distance between the logical pen position and the polygon vertices where the first vertex is in the positive X axis direction. A negative radius will rotate the arc by 180 degrees. The PDIR statement can be used the specify the starting angle.

You can specify the number of chord segments in a full circle and the number to draw. By default there are 60 segments in a full circle. Here is an example of an arc and a circle:

POLYGON 10          !Circle with radius 10
POLYLINE 10,20,3    !Arc of 3/20ths circle

For the POLYGON statement, if the number of chords drawn is less than the specified total number of chords, the polygon closure is affected. If the pen is up when the POLYGON statement is executed, the polygon is closed by drawing the last vertex to the first vertex. If pen is down, the polygon is closed by drawing the last vertex to the center of the polygon and then drawing from the center to the first vertex. The following program shows the difference:

10 GINIT
20 MOVE 35,50
30 POLYGON 10,10,8
40 MOVE 65,50
50 DRAW 65,50
60 POLYGON 10,10,8
70 END

For the POLYLINE statement, if the number of chords drawn is less than the specified total number of chords, the polygon is not closed. If the pen is up when the POLYLINE statement was executed, the first vertex is on the perimeter. If the pen is down when the POLYLINE statement is executed, the first point (logical pen position) is drawn to the first point on the perimeter. Change the previous program so that line 30 and 60 use POLYLINE statements. Execute the program again to see the effect of the pen being up or down.

30 POLYLINE 10,10,8
60 POLYLINE 10,10,8


RECTANGLE Statement

The RECTANGLE statement generates a four sided polygon described by its width and height displacement from the current pen position. The signs of the width and height determine the pen position after the RECTANGLE execution: If the width is positive, the pen position is on the left side of the rectangle. If the width is negative, the pen position is on the right side of the rectangle. If the height is positive, the pen position is in the lower corner of the rectangle and if it is negative, the pen position is in the upper corner. The following example will help clarify the last pen position

10 MOVE 50,50
20 RECTANGLE 3,5        !Pen at lower left
30 RECTANGLE 3,-5       !Pen at upper left
40 RECTANGLE -3,5       !Pen at lower right
50 RECTANGLE -3,-5      !Pen at upper right
60 END

The POLYGON and RECTANGLE statements may specify the FILL and EDGE options described later in this chapter. If neither are specified EDGE is assumed. The POLYLINE statement cannot specify these options.


User Defined Symbols

The SYMBOL statement uses a two-dimensional two- or three-column array to plot a user-defined symbol. Symbols are created with moves and draws in the symbol coordinate system; an area nine units wide and fifteen units high. The symbol may be defined to extend outside of this 9x15 cell; thus allowing you to create any size symbol you wish. The CSIZE, LDIR, and LORG statements affect the SYMBOL statement, but the SHOW or WINDOW to VIEWPORT scaling does not. This keeps the labels from becoming distorted by graphic data scaling.

The symbol data is drawn using the current pen control and line type and is clipped at the clip boundary. A move is always done to the first point and the current pen position is left at the last X,Y position specified in the array and is not updated to the next symbol position. This allows a SYMBOL to cover a group of character cells. The following program shows you how to define a SYMBOL to extend outside the character cell.

10 GINIT
20 DIM A(6,2)
30 READ A(*)
40 DATA 1,7,-2,16,7,-1,15,4,-1,21,8,-1,15,12,-1,16,9,-1,1,9,-1
50 DRAW 50,50
60 RECTANGLE 3,5
70 SYMBOL A(*)
80 END

Notice that the symbol is not closed at one end. Another X,Y data point could be added to the DATA statement to fix this, or the FILL and EDGE commands would also work. Taking the same data points as defined for the SYMBOL command, change line 70 to either the PLOT or RPLOT statements to see what happens.

70 PLOT A(*)    !Absolute Points
                 or
70 RPLOT A(*)   !Relative Points

The array is now affected by the scaling of the WINDOW values, and the data points are mapped onto the WINDOW. This causes the arrow to become larger. The PLOT statement is in absolute coordinates, that is why it is close to the origin of 0,0. RPLOT is defined in relative coordinates, being relative to the current position of 50,50.


AREA Fill Styles and Colors

The area fill styles and colors used by the PLOT, IPLOT, RPLOT, POLYGON, RECTANGLE, and SYMBOL statements are specified with the AREA statement. Area fills are specified by the FILL and EDGE options. These are described in the following paragraphs.


AREA Statement

The AREA statement defines the area fill style and color. It is qualified with either the PEN, COLOR, or INTENSITY keywords. The area color and style remain in effect until another AREA, GINIT, or SCRATCH A is executed. The IPLOT, PLOT, RPLOT, and SYMBOL statements can also change the area fill color. This is explained under "Array Specified Pen Control," later in this chapter.

When you use the AREA PEN statement the fill color is looked up in the color map table, and the fill style is set to non-dither (solid).

AREA PEN pen

Pen numbers have the same effect as described in the PEN statement except for the following two conditions. In normal drawing mode, pen 0 erases; it does not complement. In alternate drawing mode, negative pen values erase; they do not complement. The default area fill color is PEN one.

When you use the AREA COLOR or AREA INTENSITY statements the fill color is created with dithering when needed to better approximate the color specified. Use AREA COLOR to specify a color in the HSL color space and AREA INTENSITY to specify a color in the RGB color space. These are explained earlier in this chapter. Because of the calculations needed to set up dithering, AREA COLOR/INTENSITY executes slower than AREA PEN.

Run this example program to see how dithered colors look, and to see how the HSL color space works. Change line 90 to AREA INTENSITY to see how the RGB color space works.

10   REM HSL.BAS
20   GINIT
30   GCLEAR
40   KEY LABELS OFF
50   WINDOW 0,1.31,1.31,0
60   FOR L=0 TO 1 STEP .2
70     FOR H=0 TO 1 STEP 1/6
80       FOR S=0 TO 1 STEP .2
90         AREA COLOR H,S,L
100        MOVE H+.11*L,S+.11*L
110        RECTANGLE .09,.1,FILL,EDGE
120      NEXT S
130    NEXT H
140  NEXT L
150  LORG 7
160  MOVE 1.2,1.31
170  LABEL "z = Luminosity"
180  LORG 4
190  MOVE .6,1.31
200  LABEL "x = Hue"
210  LDIR PI/2
220  MOVE 1.31,.6
230  LABEL "y = Saturation"
240  END

When drawing an area in a certain color, it may be possible to produce the color faster and more accurately by specifying SET PEN followed by AREA PEN, rather than specifying AREA COLOR or AREA INTENSITY.

10   REM AREAPEN.BAS
20   GINIT
30   PLOTTER IS CRT,"INTERNAL";COLOR MAP
40   AREA INTENSITY 1/3,2/3,1
50   MOVE 10,50
60   RECTANGLE 20,20,FILL,EDGE
61   !
70   SET PEN 15 INTENSITY 1/3,2/3,1
80   AREA PEN 15
90   MOVE 40,50
100  RECTANGLE 20,20,FILL,EDGE
110  END


FILL and EDGE Options

The FILL and EDGE options control the filling and edging of an area defined by the following statements: PLOT, IPLOT, RPLOT, POLYGON, RECTANGLE, or SYMBOL. If the FILL option is specified, the area is filled with the current area fill color and style. If the EDGE option is specified, the area is edged with the current line type and pen color. When both are specified the area is both filled and edged. If neither are specified, the area is just edged with the current line type and pen color.

The following program shows the effect that the FILL and EDGE options have on an area. To see their effect change line 50 to include the EDGE and then both the FILL and EDGE options.

10 GINIT
20 AREA PEN 2
30 LINE TYPE 4
40 MOVE 50,50
50 RECTANGLE 10,10, FILL
60 END


Array Specified Pen Control

When large amounts of data are involved, or if you want to draw the same object at various places on the screen, it is often convenient to use arrays to describe the graphic coordinate values. In the PLOT, IPLOT, RPLOT, and SYMBOL statements you can specify a two or three column array. The first and second columns of the array specify the coordinate values. The optional third-column specifies the operation for each row of the array: pen-control, AREA PEN, AREA INTENSITY, LINE TYPE, PEN, FILL, and EDGE. If a two-column array is specified, the default pen control used on each row is a one, pen down after move.

This table shows the meaning of each column for each of the operations specified by column 3 of the array.

Column 1	Column 2	Column 3	Column 3 Meaning
X value	Y value	< -2	use even/odd pen control
X	Y	-2	Pen up before moving
X	Y	-1	Pen down before moving
X	Y	0	Pen up after moving
X	Y	1	Pen down after moving
X	Y	2	Pen up after moving
pen number	---	3	PEN
line type	repeat value	4	LINE TYPE
color	---	5	AREA INTENSITY
---	---	6	Start polygon mode w/FILL
---	---	7	End polygon mode
---	---	8	End of data for array
---	---	9	No operation, values ignored
---	---	10	Start polygon w/EDGE
---	---	11	Start polygon w/FILL & EDGE
---	---	12	Draw a FRAME
pen number	---	13	AREA PEN
red value	green value	14	AREA INTENSITY
blue value	---	15	AREA INTENSITY
---	---	> 15	No operation, values ignored


AREA Color

Operation 5 in column 3 selects the AREA INTENSITY color. The column 1 value is divided into red, green, and blue numbers, each five bits in length (the sixteenth bit of column one is ignored). Each five-bit number specifies a value in the range zero to sixteen. This number is subtracted from sixteen to calculate the intensity value for each of the colors: red, green, blue. Intensities range in value from zero (darkest) to sixteen (most intense).

For example, if column 1 is set to zero, then each of the three groups in column 1 is set to zero. Sixteen minus zero yields sixteen for all three groups. Sixteen is full intensity, therefore, the area fill color will be white.

The following equation calculates the value for column 1 given R, G, B values in the range zero to one.

Column1 = 16-16*R + SHIFT(16-16*G,-5) + SHIFT(16-16*B,-10)

The AREA INTENSITY red, green, and blue values can also be selected with operations 14 and 15. The range of intensity is zero (no color) to 32,767 (full intensity). Operation 14 should be done before 15, and the operation takes effect when operation 15 is done.


FILL and EDGE

A polygon is formed from a line sequence of 2 or more points with the optional FILL or EDGE specifiers. A polygon is drawn by plotting the first point, each successive point, and closed by drawing the final point back to the first point.

If FILL is specified, the polygon is filled with the current AREA fill color, and if EDGE is specified, the polygon is edged with the current PEN color. The array pen-control instructions supersede any other instructions on pen movement, LINE TYPE, and FILL and EDGE specifiers.


Graphics Rotation

The PDIR and PIVOT statements cause rotations to be applied to graphic MOVEs and DRAWs. The angle specifies the direction and amount of rotation. It is measured in a counter-clockwise direction from the positive X-axis. The current trigonometric mode (RAD or DEG) determines the units for the angle. The default trigonometric mode is RAD.


PDIR Statement

The PDIR statement specifies the rotation of IPLOT, RPLOT, POLYGON, POLYLINE, and the RECTANGLE statements. The rotation takes place about the logical position. The AXES, GRID, LABEL and SYMBOL statements are not affected by PDIR.


PIVOT Statement

The PIVOT statement causes the rotation of all lines, except those generated by the AXES, GRID, LABEL and SYMBOL statements. This includes lines generated by the MOVE, DRAW, IMOVE, IDRAW, PLOT, IPLOT, RPLOT, POLYGON, POLYLINE, and RECTANGLE statements. This rotation takes place about the logical position. The PIVOT statement effects only the starting point of the LABEL and SYMBOL statements.

If both the PIVOT and PDIR angles are set, they both have an effect on the lines being generated. The transformation on the statements affected by the PDIR commands takes place first. Then the transformations on the lines affected by the PIVOT command are done. A few examples will help demonstrate this.

10 GINIT
20 DEG
30 DRAW 50,50
40 PIVOT 0
50 PDIR 0
60 POLYGON 10,10,8
70 IDRAW 10,10
80 END

No rotations are done since both angles are set to zero. Now change line 50 to have a rotation of 90 degrees.

50 PDIR 90

The rotation of 90 effects the POLYGON statement, but not the IDRAW. This is because PDIR only affects the IPLOT, RPLOT, POLYGON, POLYLINE, and RECTANGLE statements. Now change line 40 to have a rotation of 45 degrees.

40 PIVOT 45

The POLYGON statement is rotated a total of 135 degrees, by the combination of the PIVOT 45 and the PDIR 90 statements. You will notice that the IDRAW line has been rotated only 45 degrees by the effect of the PIVOT 45 statement. Now change line 50 back to 0 degrees.

50 PDIR 0

The IDRAW line is still rotated by 45 degrees. The POLYGON statement is rotated by 45 degrees as a result of the PIVOT angle. Hopefully this example will clear up some of the confusion when applying both the PIVOT and PDIR transforms to graphic lines.


Screen Raster Images

The GSTORE statement allows you to save the current graphics screen raster image into an array and the GLOAD statement restores the graphics image to the graphics screen. The device-selector specifies the device, which must be a bit-mapped device. The CRT is assumed if no device selector is specified.

There are many uses for this capability. Images of various graphs and charts can be stored in different arrays, and then easily redisplayed. Graphs that may be very slow to generate, need only to be generated once and then displayed very fast. The graphics information in the arrays can also be written to a file for future use.

Two forms of the GLOAD and GSTORE statements are supported. The first form is compatible with the GLOAD/GSTORE statements in HP BASIC, and displays an image that fills the entire screen. The second form operates on an arbitrary sized rectangular portion of the screen. For users porting programs from HP BASIC that use the Bstore()/Bload() CSUBs supplied with HP BASIC, the "Porting HP BASIC Programs to the PC" chapter of the User's Guide, presents Bstore()/Bload() SUBs that call GSTORE and GLOAD using the integrated syntax.


Full Screen

The size of the array necessary to store a complete screen image for each display depends on the resolution and on the number of colors the display supports. GESCAPE CRT,3 can be used in a program to determine the size necessary:

10    INTEGER S(5)
20    GESCAPE CRT,3;S(*)
30    PRINT "Proper array size is";S(4);"rows and";S(5);"columns."
40    END

The following table gives the sizes for some PC display adapters. The array may be declared larger or smaller than the size given. If the array is not large enough to contain a full screen image, GLOAD stops when all the array contents have been transferred. If the array is too large, only part of the array will be used. If an attempt is made to GLOAD an image to a display that is different from the GSTORE display, unpredictable results will occur. If the color map has different values than when the image was GSTOREd, the colors will not match the original image.

Display	Array Size
CGA	Image(1:40,1:200)
MGA	Image(1:40,1:400)
HGC	Image(1:45,1:348)
EGA(merged)	Image(1:160,1:350)
VGA(merged)	Image(1:160,1:480)
640x480x16	Image(1:160,1:480)
800x600x16	Image(1:200,1:600)
1024x768x16	Image(1:256,1:768)
640x480x256	Image(1:320,1:480)
800x600x256	Image(1:400,1:600)
1024x768x256	Image(1:512,1:768)

Below is an example of the GSTORE and GLOAD statements for the VGA screen. If you have a display other than a VGA, change line 10 to the appropriate size.

10 INTEGER Image(1:160,1:480)
20 FRAME
30 DRAW 50,50
40 POLYGON 10,10,FILL
50 GSTORE Image(*)
60 END

Now that the image is stored in the array, clear the graphics screen with the GCLEAR statement. To load the image back onto the screen, use the following statement:

GLOAD Image(*)


Rectangular Blocks

GSTORE Image(*),Width,Height,Rule,Xorigin,Yorigin

When a Width and Height are specified after the image array, only a rectangular block is transferred between the array and the display. Width and Height are specified in pixels. Optionally, a Rule can be specified that instructs GLOAD/GSTORE how to combine the contents of the array with the contents of the screen. Presently, only a value of 3 is supported. This causes the contents of the array (for GLOAD) or screen (for GSTORE) to totally overwrite the target. The block will be located with the upper left corner at the current graphic position. Alternately, a position can be specified with the Xorigin, Yorigin parameters. These parameters should be specified in the current WINDOW units, not pixels or VIEWPORT units (GDUs).

For displays with 8 planes or less (256 colors or less), the image is stored with one byte per pixel. This makes images somewhat transportable among different displays. It also means that the number of elements necessary to store the image is equal to Width*Height/2. If the width is even, the array could be declared as

INTEGER Image( 1:Width/2,1:Height)

If the array is too small, an error is given. If the array is too large, the extra array elements are ignored. If GLOAD is used to display an image on a display with less colors than the GSTORE display, the results are undefined. If the color map is different than the color map in effect when the image was GSTOREd, the colors will not match the original image.


Screen Storage Formats

The format of the data stored in the array for full screen images differs from display type to display type. The data is usually packed as efficiently as possible. The following sections detail the format for common display types. The format of data stored for rectangular images was previously given.


CGA & Hercules Graphics Cards

The CGA & Hercules graphics cards use one memory bit to display each pixel on the screen. Each pixel will be stored sequentially into the integer array specified. Information is taken starting at the upper-left corner a byte at a time from each plane. The left-most (most significant) bit of each byte corresponds to the left-most screen pixel in each group of eight pixels. When accessing integers in the array, remember that the Intel 80x86 swaps bytes. Thus, the first byte in memory is found in bits 7 to 0 of the integer and the second byte in bits 15 to 8. The following diagram summarizes these rules.


EGA, VGA & SuperVGA 16 Color Graphics Cards

The EGA, VGA & SuperVGA 16 color graphics cards use four memory bits to display each pixel on the screen. Each of the four bits is stored in a different memory plane. In non-COLOR MAP mode the four planes are named Blue, Green, Red, and Intensity; HTBasic always sets the intensity bits. In COLOR MAP mode the color names do not apply and the planes are numbered 0 to 3. When ALPHA and GRAPHICS are MERGEd, information is taken starting at the upper-left-hand corner a byte at a time from each plane, starting with plane 0 and ending with plane 3. When ALPHA and GRAPHICS are SEPARATE, only 3 planes are used for graphics, so only planes 0 to 2 are GLOADed/GSTOREd. Each byte contains information for 8 pixels, but the bytes from all the planes must be considered when deciding what color a pixel is. The left-most (most significant) bit of each byte corresponds to the left-most screen pixel in each group of eight pixels. When accessing integers in the GLOAD/GSTORE array, remember that the Intel 80x86 swaps bytes. Thus, the first byte in memory is found in bits 7 to 0 of the integer and the second byte in bits 15 to 8. The following diagram summarizes these rules.

Note: In color map mode, the bits of the pen number specify which planes are set, while in non-color map mode, the pen RGB color rather than the pen number specifies which color planes are set.


Super VGA 256 Color Graphics Cards

The Super VGA 256 color graphics cards use eight memory bits to display each pixel on the screen. Each consecutive byte of memory holds the color information for a single pixel. The format is the same for both MERGEd and SEPARATE modes. When accessing integers in the GLOAD/GSTORE array, remember that the Intel 80x86 swaps bytes. Thus, the first byte in memory is found in bits 7 to 0 of the integer and the second byte in bits 15 to 8. The following diagram summarizes these rules.


S3 & ATI Graphics Cards
16 Color Modes

The S3 & ATI 16 color graphics cards use four memory bits to display each pixel on the screen. Each consecutive nibble of memory holds the color information for a single pixel. The format is the same for both MERGEd and SEPARATE modes. When accessing integers in the GLOAD/GSTORE array, remember that the Intel 80x86 swaps bytes. Thus, the first byte in memory is found in bits 7 to 0 of the integer and the second byte in bits 15 to 8. The following diagram summarizes these rules.


S3 & ATI Graphics Cards
256 Color Modes

The S3 & ATI 256 color graphics cards store the screen in the same manner as the Super VGA 256 Color graphics cards. See the preceeding 256 color graphics diagram for details.


Screen Dumps

The DUMP ALPHA and DUMP GRAPHICS statements and function keys copy the contents of either the ALPHA or the GRAPHICS screen to the DUMP DEVICE IS printing device.


DUMP ALPHA Statement

The DUMP ALPHA statement sends alphanumeric characters compatible with any ASCII printer to the current DUMP DEVICE IS device. If the graphics are visible when this command is executed, an ALPHA ON is executed before the screen dump occurs. This eliminates the graphics from the information sent to the printer.


DUMP GRAPHICS Statement

The DUMP GRAPHICS statement sends graphics information to the printer or to a file in the current printer language. The Installing and Using manual explains how to set the printer language in Chapter 4, "Printer and Image File Drivers."

If the ALPHA and GRAPHICS screens are MERGEd, then the ALPHA text will also be dumped to the printer as part of the graphics data. If the graphics are not visible when this command is executed, a GRAPHICS ON is executed before the screen dump occurs. To remove the run indicator character in the bottom-right corner of the screen, use RUNLIGHT OFF before drawing the screen image.

The GESCAPE statement is used to change the PaintJet palette as explained earlier in this chapter.


DUMP DEVICE IS Statement

The DUMP DEVICE IS statement specifies which device, file, or pipe receives the data when a DUMP ALPHA or a DUMP GRAPHICS statement is executed without a device selector. The GINIT statement causes the default DUMP DEVICE IS to be set to the value of PRT. If the optional EXPANDED keyword is included, the image is rotated by 90 degrees. For example:

DUMP DEVICE IS PRT,EXPANDED

If APPEND is specified and the DUMP is to a file, the file position is moved to the end-of-file before each DUMP. For some DUMP types, multiple images in a file are not supported. For example, the PCX file definition only supports one image per file. If APPEND is specified in these cases, the result is undefined. If APPEND is not specified, the file is overwritten with each DUMP.

The output can be sent to a device (usually a printer), file, or pipe. If the destination is a file, it must be an ordinary file or a BDAT file. Pipes are supported under UNIX, but not DOS. A pipe-specifier must begin with the "|" pipe character, and is followed by a command to start the process that the output is sent to. When a DUMP occurs, the information is sent to the process.

Many computer displays and most printers do not have square pixels. This results in a distortion when the graphics image is printed. This is normal and can be partially compensated for, if needed, by adjusting the WINDOW to apply an inverse distortion to the image drawn on the display. HTBasic partially compensates for non-square pixels by printing more than one printer pixel for each display pixel in some instances.

In some cases the softkey labels and ALPHA text are dumped along with GRAPHICS by the DUMP GRAPHICS statement. This depends on the screen driver in use, and whether ALPHA and GRAPHICS are MERGEd or SEPARATE. The two situations in which this occurs are 1) CRTA driver with GRAPHICS ON, and 2) CRTB driver with MERGE ALPHA. MERGE and SEPARATE ALPHA are explained in Chapter 8, "CRT, Keyboard, and Printer."

If you are using the CRTB driver, this problem can be easily solved using the statement SEPARATE ALPHA FROM GRAPHICS before generating the plot. If you are using the CRTA driver or have not used SEPARATE ALPHA, to solve the problem you should clear the ALPHA screen, turn the runlight off, and turn the softkey labels off before starting the GRAPHICS plot. For example:

KEY LABELS OFF
RUNLIGHT OFF
CLEAR SCREEN


Partial Screen Dumps

GESCAPE code 106 specifies a portion of the display screen to dump. The syntax is:

GESCAPE PRT,106,param(*)

The param array must be a one dimensional INTEGER array of five elements. The first element is the operation number (1 = sets boundaries for the DUMP commands). The remaining elements specify the boundary for the DUMP. The boundary is specified in screen units.

param(2) - Beginning row
param(3) - Ending row
param(4) - must be zero
param(5) - must be zero

The CONFIGURE DUMP, PLOTTER IS CRT,"INTERNAL", and GRAPHICS INPUT IS KBD,"KBD" commands reset the row parameters back to the defaults, full screen. The CONFIGURE DUMP command must be executed before the GESCAPE command. The following program demonstrates this capability:

10   INTEGER A(1:5)
20   A(1)=1   ! select code-always 1
30   A(2)=100 ! begin row-screen units
40   A(3)=300 ! End_row-screen units
50   A(4)=0   ! reserved
60   A(5)=0   ! reserved
70   DUMP DEVICE IS PRT
80   CONFIGURE DUMP TO "HP-PCL"
90   GESCAPE PRT,106,A(*)
100  FRAME
110  MOVE 0,0
120  DRAW 480,480
130  DUMP GRAPHICS
140  END


Graphics Devices

The default graphics output device is the CRT display attached to your computer. The default graphics input device is the keyboard. If a mouse is installed and active, it may also be used to specify graphic input. HTBasic allows you to specify alternate graphic devices for both input and output. The graphic output plotter language may also be specified. You can also send plotter commands directly to the output graphics device.


PLOTTER IS Statement

The PLOTTER IS statement specifies the graphics output device, file, or pipe. The default graphics output target is the CRT. Executing a PLOTTER IS statement directs all subsequent graphics output to the specified device, file, or pipe. For example:

PLOTTER IS CRT,"INTERNAL";COLOR MAP

The plotter specifier string specifies the graphics device driver. To re-select the internal CRT graphics display specify "INTERNAL". The COLOR MAP option is valid only with this specifier. It can be used on computer displays that have a color map like the EGA or VGA display adapters. If COLOR MAP is specified and the display does not have a color map, an error is returned. The SET PEN statement is used to change the color map.

The "HPGL" plotter specifier string specifies the HP graphics language. This specifier can be used in conjunction with a plotter or disk file. If a file is specified, you must also specify the physical device (hard-clip) limits. If a device is specified, the device must be able to return the physical device limits when initialized. For example:

PLOTTER IS 705,"HPGL"

specifies an HPGL plotter connected to the IEEE-488 bus on address five. The plotter can be connected to the computer over the IEEE-488 bus or the serial interface.

The hard-clip limits of the plotter may be specified. If they are not and output is going to a file, they default to ±392.75 mm in the x axis and ±251.5 mm in the y axis. If hard-clip limits are not specified and output is going to a device, HTBasic asks the device to return the p-points. The hard-clip units are specified using plotter units equal to 0.025 millimeters. The file is positioned to the beginning and is closed when another PLOTTER IS, GINIT, or SCRATCH A statement is executed. For example:

PLOTTER IS "Pictfile","HPGL",5,250,7,136

The file can be later sent to a plotting device or imported into a word processor or a desktop publishing package that supports the HP graphics language. To reset your graphic output device to the internal display execute the command:

PLOTTER IS CRT,"INTERNAL"

HTBasic supports plotter drivers other than INTERNAL and HPGL. See the Installing and Using manual, Chapter 3, "CRT and Graphic Drivers" for more information.


GSEND Statement

The GSEND statement sends command strings to the PLOTTER IS device. It is used to send commands (such as the pen speed, pen force, and character set selection commands) that are not generated by the high level graphics statements. For example:

GSEND "LBPlotter font characters."&CHR$(3)

sends the HPGL command to draw the specified string using the current plotter internal character font. Virtually any HPGL command string can be sent to the device using this statement.


GRAPHICS INPUT IS Statement

The GRAPHICS INPUT IS statement is used to specify the graphic input device. See the Installing and Using manual, Chapter 5, "Graphic Input Drivers" for more information. The default graphics input device is the keyboard. The arrow keys move the graphics position and the ENTER or CONTINUE keys specify a point. If a mouse is installed and active, it may also be used for graphic input. (Under DOS, you must first load the mouse driver software supplied with your mouse.) An example GRAPHICS INPUT IS statement is:

GRAPHICS INPUT IS 702,"HPGL"

To perform graphic input, the following statements are used:

DIGITIZE X,Y,Status$     !Wait for Point
READ LOCATOR X,Y,Status$ !Immediate Return Point

Here, X and Y are the target variables for the graphic position, and Status$ is an optional string that receives information about the state of the GRAPHICS INPUT IS device. The returned coordinates are in the units defined in the current WINDOW or SHOW statement. The Status$ string contains eight bytes with the following information:

Byte	Meaning
1	Indicates End of Stream for a device supporting
continuous point stream digitizing. Byte 1 may be used
as the pen control value in a PLOT. It is "0" if it is the
last of a continuous point stream. It is "1" otherwise,
including points from a device supporting only single
point digitizing.
2	Comma delimiter character.
3	Clip Indicator - If the character is a "0", then the point
is outside the hard-clip limits. If a "1", the point is
inside the hard-clip limits, but outside the soft-clip limits
(see CLIP). If a "2" then it is inside the soft-clip 	limits.
4	Comma delimiter character.
5	Tracking ON/OFF - If the character is a "0", then
tracking is off; if a "1", then tracking is on.
6	Comma delimiter character.
7-8	Button Positions. If S$ is the status string and B is the
button number you wish to test, then
BIT(VAL(S$[7,8]),B-1) returns one if B is down, and zero if B
is up.

A point is digitized and the coordinates of that point are assigned to the variables when the keyboard ENTER or CONTINUE keys, a mouse button, or a digitizer button is pressed.


READ LOCATOR Statement

The READ LOCATOR statement immediately reads the graphic position and stores it into the X and Y variables without waiting for a DIGITIZE operation.


SET LOCATOR Statement

The SET LOCATOR statement establishes a reference point for any subsequent graphics input statements. SET LOCATOR is only valid for graphics input devices that use relative locators.


WHERE Statement

The WHERE statement returns the current logical pen position in the x and y numeric variables and pen status information in the optional string variable. For example:

WHERE X,Y,Status$

The Status$ string contains three bytes with the following information:

Byte	Meaning
1	Pen Status - Up/Down status of the Pen. If the character
is a "1" then pen is down; if it is a "0" then the pen is up.
2	Comma delimiter character.
3	Clip Indicator - If the character is a "0", then the
point is outside the P1, P2 limits. If a "1", the point
is inside the P1, P2 limits, but outside the viewport.
If a "2" then it's inside the viewport.


Tracking Graphics Input

The SET ECHO and the TRACK statements allow you to follow the movements of the graphics input device on the PLOTTER IS device.


SET ECHO Statement

The SET ECHO statement displays a tracking cross on the screen or moves the plotter pen to the specified location. If the location is outside the clipping boundaries no action takes place.


TRACK and DIGITIZE Statements

The TRACK statement controls tracking of the input device. It enables and disables the graphic locator from following the input device position on the PLOTTER IS device during DIGITIZE statements. Tracking stops when a point is digitized, and the tracking cross is left at the location of the digitized point. When the display device is a plotter, the pen position tracks the input device. When it is the CRT, the tracking cross tracks the input device.

Use the arrow keys on the keyboard or the mouse to move the tracking cross around. Run the following two programs to get a feel for how the DIGITIZE and READ LOCATOR statements differ. Also look at how the TRACK and SET ECHO statements can be used to follow the input device on the output device. Press the ENTER key or one of the mouse buttons to read the current X,Y location in program #1. Enter the "STOP" command to terminate program #2.

Program #1                           Program #2
10 GINIT                         10 GINIT
20 PLOTTER IS CRT,"INTERNAL"     20 PLOTTER IS CRT,"INTERNAL"
30 GRAPHICS INPUT IS KBD,"KBD"   30 GRAPHICS INPUT IS KBD,"KBD"
40 FRAME                         40 FRAME
50 TRACK CRT IS ON               50 READ LOCATOR X,Y,S$
60 DIGITIZE X,Y,S$               60 SET ECHO X,Y
70 PRINT X,Y,S$                  70 GOTO 50
80 END                           80 END


Mixing Output and Input Devices

As shown by the following examples you can do some interesting things with the DIGITIZE statement by mixing the possible PLOTTER IS and GRAPHICS INPUT IS devices. The first example uses the default PLOTTER and GRAPHICS devices. Use the arrow keys on the keyboard or the mouse to move the tracking cross around. Press the ENTER key or one of the mouse buttons to read the current tracking cross location.

10 GINIT
20 PLOTTER IS CRT,"INTERNAL"
30 GRAPHICS INPUT IS KBD,"KBD"
40 TRACK CRT IS ON
50 FRAME
60 DIGITIZE X,Y,S$
70 PRINT X,Y,S$
80 END

If you have an HPGL plotter hooked up to your computer then you can try the following example. Change line 30 in the above program to setup the plotter as the input device. Chose one of the following lines for the type of communication that your plotter uses. If you are using the serial interface, make sure that the baud rate, parity, stop bits, and handshaking are setup correctly. For an IEEE-488 plotter, the device address needs to be set correctly.

30 GRAPHICS INPUT IS 9,"HPGL"   !Serial Interface
30 GRAPHICS INPUT IS 705,"HPGL" !IEEE-488 Address 5

When this program is run, the tracking cross will appear on the CRT display. By moving the pen around on the plotter, you will see the tracking cross on the screen follow the plotter movement.

You can also experiment with the other alternatives by setting the PLOTTER device to the HPGL plotter, and then varying the GRAPHICS device between the keyboard and the HPGL plotter.


Separate and Merged Alpha

The SEPARATE ALPHA FROM GRAPHICS and MERGE ALPHA WITH GRAPHICS statements provide control over how ALPHA text and graphics are displayed and manipulated on the computer screen. Both statements are presented in the following section.


Merged Alpha

The MERGE ALPHA WITH GRAPHICS statement causes all bit-planes to be used by both alpha and graphics. Alpha text is converted to graphic pixels and written into the graphic planes, overwriting any graphics data that might be present. Also, scrolling alpha text will scroll graphics, dumping either will dump both and the full range of colors are available for both alpha text and graphic output. This is the default mode for the CRTB screen driver.

Because this statement turns off COLOR MAP mode, it should be executed before any PLOTTER IS CRT, "INTERNAL";COLOR MAP statement.


Separate Alpha

The SEPARATE ALPHA FROM GRAPHICS mode is the opposite of MERGE ALPHA WITH GRAPHICS. When separate, one or more bit plane is reserved for alpha text and the remaining planes are reserved for graphic output. The alpha and graphic planes can then be turned on or off or DUMPed independently. However, ALPHA text color and graphic pens are limited as shown in the following table.  Check the Installing and Using manual to see if this mode is supported on your computer system.

Because this statement turns off COLOR MAP mode, it should be executed before any PLOTTER IS CRT,"INTERNAL";COLOR MAP statement.

The following table shows the colors available when SEPARATE ALPHA FROM GRAPHICS is used, depending on the total number of colors available.

Total	Graph	Black	White	Brown	Cyan
Colors	Pens	Alpha	Alpha	Alpha	Alpha
16	0-7	0	8	-	-
32	0-15	0	16	-	-
64	0-15	0	16	32	48
128	0-31	0	32	64	96
256	0-63	0	64	128	192


Porting Issues

HP BASIC assigns green to the first pen; HTBasic assigns white. If you prefer green or some other color, you must explicitly set a range of pen values to the color desired. The range starts with the white alpha pen value from the table above and continues to one less than the value of the brown alpha pen value. For 16 and 32 color systems, the last value should be 15 and 31, respectively.  For example, the following code changes the alpha pen from white to green on a 16 color display:

10 SEPARATE ALPHA FROM GRAPHICS
20 PLOTTER IS CRT,"INTERNAL";COLOR MAP
30 FOR I=8 TO 15
40   SET PEN I INTENSITY 0,1,0
50 NEXT I
60 END


General Input and Output
Chapter 7
General Input and Output

This chapter discusses the general I/O (input/output) statements of HTBasic. General I/O statements apply equally to screen, keyboard, printer, files, pipes, interfaces, devices, strings, and buffers. The chapters following this one discuss these I/O destinations/sources in greater detail. You should read the information in this chapter first, and then read any of the following chapters you need. BEEP, READ, and DATA statements are also presented in this chapter.

There are two pairs of statements that are used in general I/O: ENTER/OUTPUT and STATUS/CONTROL. Some interfaces also support interrupts, which can be used to force program branching on different interface conditions. Some interfaces also support background transfers. The TRANSFER statement starts background transfers.

Associated with each I/O operation is an I/O path. An I/O path contains all of the routing information necessary for the computer to transfer data between your HTBasic program and the target entity (such as a printer, data acquisition device, string, file, pipe, etc.). The ASSIGN statement is used to set up an I/O path for use in later ENTER, OUTPUT, and TRANSFER statements.


ASSIGN Statement

The ASSIGN statement is similar to the OPEN statement of other computer languages. ASSIGN makes a connection to a screen, keyboard, printer, file, pipe, interface, device, or buffer. All the information concerning this connection is saved by the ASSIGN statement in an I/O path variable. A number of attributes can be specified in the ASSIGN statement that affect how the I/O operation is done.

The I/O path variable is then used in I/O statements to specify the source or destination of the ENTER, OUTPUT, or TRANSFER. After the initial ASSIGN, subsequent ASSIGN statements can be used to redirect the I/O, change the attributes, or close the file or connection. Several I/O paths can be set up simultaneously. In fact, any number of I/O path variables may exist in your program, although some operating systems limit the number of files that can be open at one time.


Assign Syntax
Syntax

The syntax of the ASSIGN statement is:

ASSIGN @io-path [TO target] [;attrib [,attrib...] ]

where:

@io-path = a legal I/O path variable name
target =
device-selector [, device-selector...] |
file-specifier | pipe-specifier |
BUFFER {string-name$ | numeric-array(*) | '['buf-size']'}
attrib =
FORMAT {ON|OFF|MSB FIRST|LSB FIRST} |
{BYTE|WORD} |
EOL eol-chars [END] [DELAY seconds] |
EOL OFF |
APPEND |
RETURN numeric-name
buf-size = size of the buffer in bytes
eol-chars = string expression of up to 8 characters
seconds = numeric-expression rounded to the nearest
0.001 through 32.767 (default is 0)

The following paragraphs give some explanation of how to ASSIGN the different I/O targets: devices, files, pipes, and buffers. Then the different I/O attributes are explained.


Devices

A device can be the screen, the keyboard, a printer, lab instrument, or data acquisition device. The device is specified with an interface select code (ISC) or device selector. Each interface, (IEEE-488, serial, parallel, etc.) that is connected to your computer has a unique number assigned to it. When you load a device driver for an interface, a default ISC is assigned, or you can specify another ISC. The following table gives some defaults ISCs.

ISC	Device
1	CRT display
2	Keyboard
3	Graphic display
6	Bit mapped graphic display
7	IEEE-488 Board
8	2nd IEEE-488 Board
9	Serial
10	Centronix (Parallel Printer)
11	2nd Serial
12	2nd Parallel
12	GPIO
17	Various Data Acquisition Boards (no analog capabilities)
18	Various Data Acquisition Boards (with analog capabilities)
32	Processor

If multiple devices can be hooked to the interface simultaneously, as they can on the IEEE-488, then the primary address must be included with the ISC to uniquely identify the device. This is also true of data acquisition boards having one or more subsystem: A/D, D/A, DIO, etc. Together, the ISC and primary address are called a device selector. Some IEEE-488 devices also require one or more secondary addresses. Each primary or secondary address should be specified with two digits. Thus 1 should be specified as 01. The total length of the device selector can be 15 digits. The following examples illustrate these rules. To do I/O with an IEEE-488 device (assuming the default ISC) at primary address 2 and secondary address 6, use this ASSIGN statement:

ASSIGN @Dvm TO 70206

To do I/O with an IEEE-488 device at primary address 3:

ASSIGN @Scope TO 703

To use analog output with a data acquisition board set to ISC 18 and 02 as the primary address for analog output, use this ASSIGN:

ASSIGN @Daq TO 1802

To do I/O with a device hooked to a serial port at ISC 9, you could use:

ASSIGN @Dvm TO 9

A device can have more than one I/O path name, each with different attributes, associated with it.

An I/O path name can have more than one IEEE-488 device assigned to it. If multiple devices are specified, they must be on the same interface. When OUTPUT is made to an I/O path assigned to multiple devices, all the devices receive the data. When ENTER is made from multiple devices, the first device specified sends data to the computer and to all the other devices assigned to the I/O path name. When CLEAR, LOCAL, PPOLL CONFIGURE, PPOLL UNCONFIGURE, REMOTE, or TRIGGER are made on multiple devices, all the devices receive the IEEE-488 message.

It is possible to do I/O with a device without using an I/O path. But, when an I/O statement does not specify an I/O path variable, a temporary I/O path is created internally, used for the duration of the statement, and then discarded. This is usually slower than to ASSIGN an I/O path once and use it throughout the program.

OUTPUT @Scope;A(*)    ! Usually faster
OUTPUT 703;A(*)       ! Usually slower


Files

A file is opened when the ASSIGN statement specifies a file-specifier. The file's position pointer is set to the beginning if the APPEND option is not specified and set to the end if it is. The file position is updated to point to the next byte to be written or read after each ENTER or OUTPUT statement. The ASSIGN statement will not CREATE a file if it does not exist. You should use the CREATE statement before ASSIGNing the file if the file does not yet exist.

CREATE "STEPHANI.E",1
ASSIGN @File TO "STEPHANI.E"


Pipes

Pipes are supported under UNIX, but not under DOS. A process is created with the command specified in the pipe-specifier. If the pipe-specifier begins with the "|" pipe character, then OUTPUT can be used to send information to the process. If the pipe-specifier ends with the pipe character, then ENTER can be used to get information from the process. For example:

ASSIGN @Users TO "finger |"


Assign Buffers
Buffers

Buffers are typically used as the source or destination of a TRANSFER. The statement

ASSIGN @Iopath TO BUFFER [300]

allocates an unnamed buffer and assigns it to an I/O path name. Unnamed buffers can only be accessed through their I/O path. The

ASSIGN @Another TO BUFFER X(*)

statement assigns an I/O path name to the variable X(*) which must be declared as a buffer in a COM, DIM, INTEGER, or REAL statement. Numeric data stored in a named buffer should not be accessed through the name of the array if the byte order of the computer and the byte order of the data is different. In general, STATUS and CONTROL are the preferred method for accessing the data.

The buffers specified in these ASSIGN statements may now be used in ENTER, OUTPUT, or TRANSFER statements.


Attributes

The attributes of an I/O path allow you to change certain aspects of how data is transferred. The attributes can be specified when the initial ASSIGN is made, or the attributes of a previously ASSIGNed I/O path may be individually changed by omitting the "TO target" portion of the statement:

ASSIGN @Julie;FORMAT OFF

Additional attributes of a particular device, such as the baud rate of a serial device, are changed using STATUS, CONTROL, READIO, and WRITEIO statements. These statements are explained later in this chapter.


FORMAT Options

One piece of information stored in the I/O path is whether to transfer information in ASCII or binary (internal) format. ASCII transfers are called FORMAT-ON-format and binary transfers are called FORMAT-OFF-format. If FORMAT is not explicitly specified in the ASSIGN statement, a default format is used. For interfaces, buffers, devices, LIF ASCII files, and pipes the default is FORMAT ON; for BDAT and ordinary files, the default is FORMAT OFF.

This example explicitly specifies FORMAT ON:

10   ASSIGN @File1 TO "TEMP.TXT";FORMAT ON

When FORMAT ON is specified in the ASSIGN statement, data items are output in a readable ASCII format. Numeric items are output in the standard ASCII numeric format and the ASCII characters in a string are output. If the default output formats are not acceptable, the USING and IMAGE statements can be used to format the data as needed.

When FORMAT ON is specified, data items are entered with the data expected to be in readable ASCII format. Reading data with FORMAT ON works with most devices. For other devices, most formats can be handled using IMAGE and USING statements. Numeric data must be scanned to find legal combinations of characters that make up a numeric value. String data must be scanned for end-of-string terminators.

When FORMAT OFF is specified in the ASSIGN statement, data is transferred in internal format. LSB/MSB FIRST can be used in the ASSIGN statement to specify the order in which the data bytes are sent or received. If LSB/MSB FIRST is not specified, data sent to devices is sent MSB FIRST for compatibility with HP devices; data sent to files, pipes, and operating system devices is stored in the form must natural to the computer's processor. Of course, LSB/MSB FIRST can always be used to override these defaults.

20   ASSIGN @Dev1 TO 9;FORMAT LSB FIRST

The internal format for INTEGER numbers is a two byte, two's complement, binary integer. The internal format for REAL numbers is an eight byte, IEEE compatible floating point number (see IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Std. 754-1985). The internal format for COMPLEX numbers is two real numbers. The first eight bytes contain the real part of the number and the last eight bytes contain the imaginary part.

The format for strings depends on the source or destination of the I/O statement. For ordinary files and pipes, the internal format for strings is a null-terminated string.

The string format for devices and BDAT files consists of a four-byte-integer string length followed by the string contents. An even number of bytes is always transferred, therefore, if the string is odd in length an extra pad byte is transferred. The LSB/MSB FIRST option can be used to determine the byte ordering of the four byte string length.

For LIF ASCII files FORMAT OFF has no effect. Data is always transferred as ASCII strings proceeded by a two byte integer length and padded by a trailing space if necessary to make the string length even. The string length is always transferred with MSB FIRST.


BYTE and WORD

When BYTE is included in the ASSIGN statement, the data is sent and received as bytes, even if the interface is capable of 16-bit transfers. The upper 8 bits are zeros. (Note: The "W" IMAGE specifier will send a word on a 16-bit interface, even if BYTE is specified in the I/O path.) The WORD attribute can only be included in the ASSIGN statement if the interface is capable of 16-bit transfers. The data is then transferred a word at a time. The WORD attribute is primarily intended for transfer of FORMAT OFF data and can have unexpected side effects with FORMAT ON.

When neither BYTE nor WORD is included in the ASSIGN statement, the default is BYTE. Syntax examples including the BYTE and WORD attributes are:

30   ASSIGN @Gpio TO 15;FORMAT OFF,WORD
40   ASSIGN @Meter TO 711,712;BYTE


EOL

The default End-Of-Line for OUTPUT is a carriage return (CR) followed by a line feed (LF) sent with no END indication and followed by no DELAY. Specifying END causes an interface specific END indication to be sent with the EOL. On the IEEE-488, END causes EOI to be sent with the final character of the EOL. Specifying DELAY causes the computer to pause for the specified number of seconds after sending the EOL and before allowing the program to continue. The exact delay time depends on the timing resolution available on the computer you are using. On the PC, the timing resolution is about 55 milliseconds. The default EOL (CR/LF) can be restored by specifying EOL OFF.

Examples:

50   ASSIGN @Slow_printer TO 10;EOL CHR$(10) DELAY .1
60   ASSIGN @Jet TO 701;EOL CHR$(13)&CHR$(10) END
70   ASSIGN @Ep TO PRT; EOL OFF ! Restore default


APPEND

If APPEND is specified, the file position is moved to the end-of-file after the ASSIGN. If it is not specified, the file position is moved to the beginning of the file. APPEND is supported on BDAT and ordinary files, but not LIF ASCII files.


RETURN

RETURN can be used with ASSIGN to test whether the ASSIGN operation was successful. If not successful, the error number is returned in the variable specified, otherwise a zero is returned. The following example shows one possible use for this feature: ASSIGNing a file, but creating the file only if it does not exist:

10    INTEGER Result
20    F$="KRISTI.TXT"
30    REPEAT
40      ASSIGN @I TO F$;RETURN Error
50      IF Error THEN
60        IF Error=56 THEN
70          PRINT "File not found: creating ";F$
80          CREATE F$,10
90        ELSE
100         CAUSE ERROR Error ! Let the error occur
110       END IF
120     END IF
130   UNTIL NOT Error
140   END


Closing an I/O Path

Closing an I/O path makes the path invalid. All subsequent ON event statements for the closed I/O path are not acted upon. If an I/O path name has not been declared in a COM statement it may be closed in the following ways:

1. Explicitly close a path by executing

ASSIGN @Io-path TO *

2. Re-assigning the I/O path

ASSIGN @Io-path TO target

3. Exiting the subprogram with SUBEND, SUBEXIT, ON...RECOVER, or RETURN value

4. Stopping the program with END, GET, LOAD, SCRATCH, SCRATCH A, SCRATCH C, or STOP.

If an I/O path name has been declared in a COM statement it may be closed in the following ways:

1. Explicitly close a path by executing

ASSIGN @Io-path TO *

2. Re-assigning the I/O path with

ASSIGN @Io-path TO target

3. Executing SCRATCH A, SCRATCH C, SUBEND, SUBEXIT, ON...RECOVER, or RETURN value.

4. Executing EDIT, GET, or LOAD in a program that has a COM statement that does not match the COM statement that contains the I/O path name.


OUTPUT Statement

OUTPUT can be used to send numeric data, array elements, character strings, sub-strings, or full arrays. Full arrays are specified with the full array specifier, "(*)", and are output in row major order. Row major order means the right-most subscript is incremented before the subscript to the left of it. If the default output formats are not acceptable, USING/IMAGE can be used to format the data as needed. If the data is sent with FORMAT OFF, then just the internal representations are sent, with no item separators. If the data is output with FORMAT ON, then data is sent in ASCII, printable characters. Numeric and string items are sent as described below.


Output Numeric Items
Numeric Items

Numeric items are converted to standard numeric format: The number is rounded to twelve significant digits. If the absolute value is outside the range 1E-4 to 1E+6, then the number is output in scientific notation. If the number is negative, a leading minus sign is sent; if the number is positive, a leading space is sent instead. Trailing zeros or decimal point are not output. If a comma follows the output item, then a comma is sent as an item separator. If a semicolon follows the output item, then no item separator is sent. If a full array is sent, a comma will be sent to separate each element unless a semicolon follows the output item (the array).

Complex items are output in rectangular form, real part first, then a comma, and finally, the imaginary part. Real and imaginary parts are formatted in standard numeric format as explained in the previous paragraph. If a semicolon follows the complex item then the comma separating the real and imaginary parts is suppressed.


Output String Items
String Items

String items are sent by sending each character in the string. If a comma follows the output item, then CR/LF are sent as an item separator. If a semicolon follows the output item, then no item separator is sent. If a full array is sent, an item separator will be sent to separate each element unless a semicolon follows the output item (the array).

Note: CR/LF is the string item separator and is not affected by the EOL sequence definition in the ASSIGN statement.


End of Line

After all of the OUTPUT items have been sent and if the statement did not end with a semicolon or comma, then an End-of-Line (EOL) Sequence is sent. The default EOL is CR/LF, but may be redefined in the ASSIGN statement.

The following examples illustrate most of these rules. For the examples, assume that the following lines have first been executed:

10    REM OUTPUTEX.BAS
20    DIM R(1),A$(1)[1]
30    R(0)=-1
40    R(1)=+1
50    MAT A$=("A")
60    ASSIGN @I TO some device

In the Characters Output, the EOL (which defaults to CR/LF), is shown as <eol>, the string item separator (which is CR/LF), is shown as <crlf>. Spaces are shown as underlines, "_", to make them stand out.

Program lines	Characters output
70   OUTPUT @I;1.E+5,1.E+7	_100000,_1.E+7<eol>
80   OUTPUT @I;1;-1	_1-1<eol>
90   OUTPUT @I;R(*),	-1,_1,
100  OUTPUT @I;CMPLX(1,1.23456789012345E+7)
_1,_1.23456789012E+7<eol>
110  OUTPUT @I;CMPLX(1,1);	_1_1
120  OUTPUT @I;"B";"C","D"	BC<crlf>D<eol>
130  OUTPUT @I;A$(*);	AA

In line 70, 1.E+7 is listed in scientific notation because it is outside the range 1E-4 to 1E+6. The numbers are both positive so a leading blank is output before each. The default EOL is output at the end. In line 80, the -1 has no leading space; the space is replaced with a negative sign. And the semicolon between the two numbers suppresses the comma that would normally be output between the two.

In line 90, an array is output. Notice the full array specifier. The comma following the array causes an item separator to be output between each element. The numeric item separator is a comma. Line 120 shows an example of a string item separator, CR/LF. Line 90 also shows that a trailing comma will suppress the EOL.

Line 100 shows that the real and imaginary parts of a complex number are separated by a comma. This line also shows the default rounding of numbers to 12 significant digits. Remember that if the default output formats are not suitable for your application, you may use OUTPUT USING to define your own. Line 110 shows that a semicolon will suppress the comma between the real and imaginary parts. It also shows that a trailing semicolon will suppress the EOL.

Line 120 demonstrates the effect on string output of commas and semicolons. The semicolon suppresses the item separator that would normally follow the "B". The comma causes the normal string item separator, CR/LF, to be output after the "C". And if no semicolon or comma is at the end of the statement, an EOL is output after the final string.


Output END
END

An optional END may be used after the last data item. If USING is not specified, then END: 1) suppresses the EOL sequence from being output after the last item, 2) sends an EOI signal with the last character of the last item sent to an IEEE-488 device, and 3) truncates a file. A comma before the END will output an item terminator (a comma for numeric items or a CR/LF for string items). For example:

OUTPUT @I;"Time: ";TIME$(TIMEDATE) END


ENTER Statement

The ENTER statement can be used to enter numeric data, array elements, character strings, sub-strings, or full arrays. Full arrays are specified with the full array specifier, "(*)", and are entered in row major order. If the default ENTER formats are not acceptable, USING/IMAGE can be used to format the data to the specifications of the I/O device. If the ENTER is done with FORMAT OFF, then data is expected in the internal representations given above, with no item or statement terminators. If FORMAT is ON, then data is expected in ASCII printable characters as explained below.


Enter Numeric Items
Numeric Items

The number builder is used with numeric items to change ASCII data to numeric data for assignment to a numeric variable. Leading non-numeric characters are ignored. Blanks are ignored where ever they occur. The number is expected to be in the form:

[sign] mantissa [E exponent] item-terminator

where:

sign = + | -
mantissa = [digits] [.] [digits]
exponent = [sign] digits

The mantissa must have at least one numeric digit, whether it be before or after a decimal point. Because REAL numbers have only fifteen digits of precision, any mantissa digits after the 15th digit are considered to be "0". The "E" before the exponent can be either upper or lower case. The item-terminator is any non-numeric character. The item-terminator can either be an EOI on the last character of the number, or any non-numeric character. The entire ENTER statement must also be properly terminated.

10  DIM A$[30]
20  A$="hello + 1 2 3 goodbye"&CHR$(13)&CHR$(10)
30  ENTER A$;X,B$

This example will assign 123 to X and "oodbye" to B$. The "g" was used to terminate X and thus is not present in B$.

A complex item is entered in rectangular form, real part first, followed by the imaginary part. The rules for each part are the same as the rules for numeric items given above.


Enter String Items
String Items

String items are terminated with either a LF, a CR/LF, an EOI signal, or upon filling the dimensioned length of the string. The LF or CR/LF terminators are not entered into the string.


Statement Termination

For both string and numeric items, if the last item was not terminated with a LF, CR/LF, or an EOI signal, then additional characters are read (but thrown away) until one of these terminators is received. If no terminator is found within 255 characters, an error is reported.

10  DIM A$[30],B$[2]
20  A$="hello + 1 2 3 goodbye"&CHR$(13)&CHR$(10)
30  ENTER A$;B$

In this example, because B$ has a dimensioned length of two characters, it is assigned the value "he". The remaining characters are thrown away, and the CR/LF terminate the ENTER.

Note: LF or CR/LF are always used for the termination of ENTER, regardless of the setting of EOL in the ASSIGN statement.


Formatted I/O

OUTPUT, ENTER, PRINT, DISP, and LABEL allow you to control the format of both output and input data. The format is specified as an IMAGE. The IMAGE string can immediately follow the USING keyword as a string (literal or variable) or a line number or label can follow the USING keyword to reference an IMAGE statement that contains the format data. For example:

10    OUTPUT CRT USING "ZZZ.DDD";1.2
20    IMAGE ZZZ.DDD
30    OUTPUT CRT USING 20;1.2

An IMAGE string consists of a list of one or more image items. The items specified in the image list are acted upon as they are encountered. Each image list item should have a matching output (or enter) item. Processing of the image list stops when no matching output item is found. However, when the last item in the image list is used, the image list is reused starting at the beginning to provide matches for all remaining output items. FORMAT ON is used in connection with USING, even if FORMAT OFF has been specified.

If more decimal places to the left of the decimal point are required to output a numeric item than are specified in the image specifier, an error is generated. If M or S is not specified, then a minus sign will take up one digit place. If the number contains more decimal places to the right of the decimal point than are specified in the image field, the output is rounded to fit.

If the number of characters specified in an image specifier for a string is less than the number of characters in a string, then the remaining characters are ignored. If the number of characters specified is greater than the number of characters in a string then trailing blanks are used to fill out the image field.


IMAGE Interpretation

Each character in the IMAGE string has a special meaning. For example, the letter A means "an alphanumeric character must be printed here", the letter D means "a decimal numeric value must be printed here", and the letter X means "a space character must be printed here." The order in which data items are specified in the USING statement must match the IMAGE string. For Example:

100 PRINT USING 110;"Base Price:",6995
110 IMAGE 11A,X,4D

In this example, the print format is specified in the IMAGE statement in line 110. The IMAGE string 11A,X,4D defines two "print fields" or "print zones" separated by one extra space (X). The first print field (11A) specifies that the first data item in the PRINT USING statement must be a character string of not more than eleven characters in length. The second print field (4D) means that the second data item must be a numeric value of not more than four digits to the left of the decimal point. The fractional part of the number, if any, is rounded off in this case. Here is the resulting output:

Base Price: 6995

When line 100 is executed, the alphanumeric string "Base Price:" and the numeric constant "6995" are sent to the specified output device. The default print format normally used for FORMAT ON output is suppressed.

Notice that each print field specified in the format string has an accompanying data item specified in the PRINT USING statement. The data items are also of the correct type, a character string for the A field and a numeric value for the D field. If the data items were reversed in line 100, a data mismatch would occur, and program execution would halt with an error. If too many data items were specified in line 100 (three data items, for example instead of two), then the IMAGE string would have been reused and the third data item would need to be a string or an error would occur, and program execution would again halt. So, it is important that the type of data items specified in a PRINT USING statement, and the order in which they are specified, match the specifications of the format string.

Complex values and variables are treated as if they were two real variables. Therefore, no special item specifiers are needed for complex numbers.


Image Syntax
Syntax

Some item specifiers can be preceded by a numeric integer constant from 1 to 32767 that specifies the size of the field or the number of repetitions. The exact syntax of the image specifier is:

image-specifier =
# | % | K | -K | H | -H | B | W | Y | + | - |
[repeat-factor] A... |
[repeat-factor] X... |
[repeat-factor] /... |
[repeat-factor] L... |
[repeat-factor] @... |
numeric-specifier |
"string-literal"
numeric-specifier =
[S|M] [left-digits] [.|R] [right-digits] [exp]
left-digits = [repeat-factor] {D|Z|*}...
right-digits = [repeat-factor] D...
exp = E | ESZ | ESZZ | ESZZZ
repeat-factor = integer-constant (1 to 32767)


OUTPUT, etc.

IMAGE specifiers have the following meanings in DISP, LABEL, OUTPUT, and PRINT statements:

#	Suppress automatic output of EOL following the last item.

%	Is ignored in OUTPUT images.

K	Output a number or string in default format, with a period for the radix.

-K	Means the same thing as K.

H	Output a number or string, default format, comma radix.

-H	Means the same thing as H.

B	Output a byte, like the CHR$ function. If the value is larger than 32767, 255
is sent. If the value is smaller than -32768, 0 is sent. If the value is in between, it is rounded to an integer and the least significant byte (CINT(value) MOD 256) is sent.

W	Output a word in 2's complement 16-bit integer form. If the value is larger
than 32767, 32767 is sent. If the value is smaller than -32768, -32768 is sent. If the interface is 16-bit, the word is output in one operation (even if the BYTE attribute was used in the I/O path). If the interface is 8-bit, the byte ordering depends on the LSB/MSB attribute of the I/O path. If the destination is a string, native byte ordering is always used (LSB FIRST on a PC, MSB FIRST on a Sun or HP Workstation). If the WORD attribute was specified in the I/O path, a pad byte will be output before the word when necessary to achieve word alignment.

Y	Means the same as W, except that word alignment is not done, and the
BYTE attribute is not ignored.

+	Change the automatic output of EOL to carriage-return after the last item.

-	Change the automatic output of EOL to line-feed after the last item.

M	Output a minus sign if negative, a blank if positive.

S	Output the sign of the number (+ or -).

D	Output one numeric digit character. The leading zero's are replaced
by blanks, a minus sign is displayed on negative numbers.

Z	Means the same thing as D except leading zeros are displayed.

*	Means the same thing as D except leading zeros are replaced with
asterisks.

.(period)	Output a decimal-point radix indicator.

R	Output a comma radix indicator.

E	Output an 'E', a sign character, and a two-digit exponent.

ESZ	Output an 'E', a sign character, and a one-digit exponent.

ESZZ	Output an 'E', a sign character, and a two-digit exponent.

ESZZZ	Output an 'E', a sign character, and a three-digit exponent.

A	Output an alphanumeric string character.

X	Output a blank.

/	Output a carriage-return and line-feed.

L	Output the current EOL sequence. The default is CR/LF.

@	Output a form-feed character.

"string-literal"	Output the characters in the string literal. Remember to double the quote marks when the IMAGE is inside a string literal.


ENTER

IMAGE specifiers have the following meanings in an ENTER statement:

#	Causes the statement to terminate when the last item is terminated. No
statement terminator is needed, EOI and LF are item terminators, and early termination is not allowed.

%	Is the same as # except EOI causes early statement termination when it
terminates an item.

K	Allows free-field entry. For numerics, entered characters are sent to the
number builder, leading non-numeric characters and blanks are ignored, trailing non-numeric characters and characters sent with EOI true are delimiters. For strings, entered characters are sent to the string. A CR may be sent to the string if it is not followed by a LF. The string is terminated by CR/LF, LF, character received with EOI true, or the string dimensioned length being filled.

-K	Is like K except LF and CR/LF are not terminators.

H	Is the same as K except a comma is the radix indicator and a period is a
non-numeric character.

-H	Means the same as -K for strings, and H for numbers.

B	Demands one Byte, like the NUM function.

W	Demands a 16-bit Word (2's complement integer). If the interface is 16-bit,
the word is entered in one operation (even if the BYTE attribute was used in the I/O path). If the interface is 8-bit, the byte ordering depends on the LSB/MSB of the I/O path. If the source is a string, native byte ordering is always used (LSB FIRST on a PC, MSB FIRST on a Sun or HP Workstation). If the WORD attribute was specified in the I/O path, a pad byte will be entered before the word when necessary to achieve word alignment.

Y	Is the same as W, except that word alignment is not done, and the BYTE
attribute is not ignored.

+	Indicates an END (EOI) is needed with the last character of the last item to
terminate the ENTER statement. LFs are no longer statement terminators, but are still item terminators.

-	Indicates a LF is needed to terminate the ENTER statement. EOI is ignored;
other END indicators cause an error.

S	Same meaning as D.

M	Same meaning as D.

D	Demands one character for each D, or repeat count. Non-numerics are
consumed while fulfilling the count but also delimit the number. Blanks embedded in the number are ignored.

Z	Same meaning as D.

*	Same meaning as D.

.(period)	Same meaning as D.

R	Has the same meaning as D, plus the number builder is instructed to use a
comma as the radix indicator and a period as a non-numeric character.

E	Is treated the same as 4D.

ESZ	Same as 3D.

ESZZ	Same as 4D.

ESZZZ	Same as 5D.

A	Demands one alphanumeric string character.

X	Enters a character and discards it.

/	Skips all characters to the next LF. EOI is ignored.

L	Ignored in ENTER.

@	Ignored in ENTER.

"string-literal"	One character is skipped for each character in the string literal. Remember
to double the quote marks when the IMAGE is inside a string literal.


Creating Format Strings

The following examples illustrate how to combine characters into IMAGE strings. These examples use PRINT, but DISP, LABEL, or OUTPUT could also have been used to direct the output to various destinations.

The A character defines a field for alphanumeric character strings. The operator is specified in the form nA where n is an integer from 1 through 32767. If n is not specified, then 1 is used.


PRINT Examples

This example shows creation of an alphanumeric field:

110 A$ = "John Doe"
120 IMAGE 15A,2X,24A
130 PRINT USING 120;"Student Name:",A$

In line 120 above, the IMAGE item defines an alphanumeric field with 15 alphanumeric positions, 2 extra spaces, and then 24 more character positions. In line 130, the string constant "Student Name:" is printed in the first field, and "John Doe" in the last field.

The following shows how the output is printed relative to the field description. The first line shows the fields specified by the IMAGE string. The second line shows the PRINT output.

AAAAAAAAAAAAAAAXXAAAAAAAAAAAAAAAAAAAAAAAA
Student Name:    John Doe

Notice that the character strings are left justified in the fields. This means that the first character in the string is printed in the left-most position in the field. The character string "Student Name:" only fills 13 character positions, the remaining positions are filled with space characters. John Doe fills 8 positions and the remaining 16 positions in that field are filled with space characters. Character strings larger than the specified field will be truncated.

The print position is set to a new line after each line is printed unless the IMAGE format ends with "#" to suppress the EOL. You would want to do this if you needed to continue output on the same line with another output statement.

Here is another PRINT USING example:

10    IMAGE "ERROR: ",2D,", ",K
11    Esc$=CHR$(27)
20    PRINT USING "A, ""[H"", A, ""[J"", #";Esc$,Esc$
25    PRINT USING 10;ERRN,"in line "&VAL$(ERRLN)
30    PRINT USING 10;19,"Out of range!"
40    PRINT USING 10;Error_code,"Oops!"
50    PRINT USING " ""The value of PI is"",X,1D.10D ";PI


ENTER Example

The following examples demonstrate how the ENTER USING rules are used to input floating point and integer numbers.

10    DIM A$[22]
20    A$="Dollars: $34.56 Total"
30    ENTER A$ USING "K";X1
40    ENTER A$ USING "14D";X2

In line 30, the number builder ignores non-numeric characters preceding the number and stops at the first character that is not part of the number so that X1 equals 34.56. In line 40 the number builder stops after 14 characters ("Dollars: $34.5") are input so that X2 equals 34.5.

10 A$ = "2XX+3Y"
20 ENTER A$ USING "D,5D";X,Y

In this example, the variable X is assigned the value 2, and Y is assigned 3.


Using END
END

An optional END may be used after the last data item. If USING is specified, then the effect of the END is quite different than if USING is not specified. What the HP BASIC manuals say should happen and what actually happens are different. No general rule seems to explain what really happens. Whether this is an HP BASIC bug or not is hard to say, but HTBasic faithfully emulates the HP behavior except in one exceptional case in which the HP behavior will almost certainly cause an instrument to read an extraneous, empty data item. This case is pointed out below. An END after the last item in an OUTPUT USING statement will have the following effect:

1) If the last image specifier does not have an output item (X, /, @, L, and "literals"), then EOL is suppressed, including alternate EOLs specified by + or -, and no EOI is sent. Exception 1: If the IMAGE specifier is L and END is specified in the ASSIGN then EOI is sent with the EOL whenever the EOL is sent.)

2) If the last image specifier does have an output item (K, H, D, Z, *, A, B, W, and Y) then EOL is unaffected and EOI is sent with the last byte sent. Exception 2.1: If END is also used in the ASSIGN statement then two EOIs are sent, one with the last output item and one with the EOL. This is the exception that HTBasic does not emulate; the general rule 2 is followed. Exception 2.2: If the last output item is a string with a length of zero, and the image specifier is K, and # has suppressed the EOL, then no EOI is sent. As an example, this statement will output one character, "A", with no EOI:

OUTPUT 717 USING "K,K,#";"A","" END

3) If the last image specifier changes the default EOL (#, +, and -), then use the next to last specifier to determine whether to use rule 1 or 2, above.


TRANSFER

The TRANSFER statement sets up unformatted data transfers between memory and a device. The data transfer normally occurs in the "background." That is, the BASIC program continues to run in the "foreground" simultaneously with the background transfer. Optionally, the TRANSFER statement can wait until the transfer is complete before continuing. The syntax is

TRANSFER @source-io-path TO @dest-io-path
[; [term-list] [,] [EOR(term-list)] [,] [type]  ]

Use the ASSIGN statement to initialize the source and destination I/O paths. The optional commas are only needed when items occur on both sides of the comma.


Examples

TRANSFER @Device TO @Buffer
TRANSFER @Buff TO @Logger;CONT
TRANSFER @Rs232 TO @Buff;DELIM CHR$(13)
TRANSFER @Path TO @Buff;RECORDS 16,EOR(END)


Support

TRANSFER is not supported on all interfaces. The interface hardware must have the necessary circuitry and the device driver must have the proper software support.


Transfer Buffers
Buffers

The transfer operation must be between a buffer and a device. A buffer must be declared as the source for an outbound transfer, or as the destination of an inbound transfer. One buffer can simultaneously be used for an outbound transfer and an inbound transfer. A transfer directly between two devices is not supported.

Buffers may be unnamed or named. An unnamed buffer is created, assigned an I/O path, and given its size by the ASSIGN statement. A named buffer is a previously declared REAL, INTEGER, or COMPLEX array, or a string scalar (declared in a COM, DIM, INTEGER, REAL, or COMPLEX statement) that has been ASSIGNed to an I/O path. Unnamed buffers are usually preferred because the size can be as large as available memory and no side-affects are possible by accessing the buffer through its variable name.

Buffers are circular; each buffer has a fill and empty pointer as well as a count. The fill pointer is used by an inbound transfer to identify the next location for data to be stored (inserted). The empty pointer is used by an outbound transfer and points to the next location for data to be output (removed). A value of one for either pointer means the first byte of the buffer. When the fill and empty pointers have the same value, the count can be examined to determine whether the buffer is empty or full.

The I/O path assigned to the buffer is called the buffer-I/O path. The I/O path assigned to the device is called the non-buffer-I/O path. The buffer should be accessed only with the buffer-I/O path. The count, fill, and empty pointers can be examined using STATUS on the buffer-I/O path. OUTPUT @buf or an inbound transfer are used to place data into a buffer. ENTER @buf or an outbound transfer are used to read and remove data from a buffer. The variable name of a named buffer should generally not be used to access the data in the buffer since the data in the buffer is unformatted and may even have the wrong byte order.


Transfer Type

The type of the transfer can be specified as CONT, WAIT, or left unspecified.

If WAIT is specified, the transfer executes in foreground mode. Program execution does not proceed beyond the TRANSFER statement until the transfer terminates. If an error occurs, it is reported with the line number of the TRANSFER statement. If WAIT is not specified, execution continues past the TRANSFER statement and the transfer takes place in the background. Then if an error occurs, the error is not reported until the non-buffer-I/O path is referenced. The error line reported is not that of the TRANSFER, but of the statement where the non-buffer-I/O path was referenced.

If CONT is specified, TRANSFER executes continuously. For an inbound transfer, execution pauses when the buffer is full and continues when space is available in the buffer. For an outbound transfer, execution pauses when the buffer is empty and continues when the buffer has data available. If CONT is not specified, the end-of-transfer occurs when an outbound transfer empties the buffer or an in-bound transfer fills the buffer. Or if a termination method has been specified as explained below, the transfer terminates when the condition occurs.

Both WAIT and CONT can be specified together if a transfer is already active for the buffer in the opposite direction. The transfer will be continuous, but will run in the foreground.

If neither WAIT nor CONT is specified, the transfer occurs in the background. The end-of-transfer occurs when an outbound transfer empties the buffer or an in-bound transfer fills the buffer. Or if a termination method has been specified as explained below, the transfer terminates when the condition occurs.


Transfer Method

A couple of methods are available for accomplishing the transfer: DMA (direct memory access) and interrupts. DMA is the fastest method and will be used automatically, if possible. A DMA channel must be available, the interface must have the necessary hardware, and DELIM can not have been specified. If DMA can not be used, interrupts are used.


Transfer Termination

A term-list can be used to specify a list of conditions that cause the transfer to end. One or more of the following conditions can be used:

•  COUNT Bytes
•  DELIM Character
•  END
•  RECORDS Number

If COUNT is specified, the transfer terminates after the specified number of bytes has been transferred.

If DELIM is specified for an inbound transfer, then the transfer is terminated after the specified character is detected. DELIM is not allowed with outbound transfers. If the delimiter string is zero length, delimiter checking is disabled. DELIM prevents DMA from being used; interrupts will be used instead.

If END is specified for an inbound transfer, the transfer terminates when the device dependent signal is received. On the IEEE-488 interface, END is the EOI signal. When an inbound transfer is terminated in this way, bit 3 of register 10 is set. For an outbound transfer, END does not specify a termination condition, but rather specifies that the device dependent signal (EOI) is sent with the last byte sent.

If RECORDS is specified, the transfer terminates when the specified number of records has been transferred. An EOR(term-list) must be specified, defining what will be considered a record for the purpose of this particular transfer. For inbound transfers the legal end-of-record termination conditions are COUNT, DELIM, and END, or some combination of these three. For outbound transfers only COUNT can be used to define a record, although END can be used to specify that the device dependent signal (EOI) is sent with the last byte of each record.


ON EOR and ON EOT

The ON EOR and ON EOT statements can be used to generate an event when an end-of-record or end-of-transfer occurs. The WAIT FOR EOR and WAIT FOR EOT statements can be used to stop further statement execution until an end-of-record or end-of-transfer occurs.


Termination

To terminate a CONT, continuous mode, outbound transfer without leaving data in the buffer, use the following sequence of statements:

CONTROL @Buff,8;0
WAIT FOR EOT @Non_buff


Hanging and Premature Termination

HTBasic will not enter a stopped state until all transfers are completed. Likewise, HTBasic will not exit a program context until transfers started in that context are finished. The following statements also cause the computer to "hang" until all transfers complete: GET, LOAD, RETURN, STOP, SUBEND, SUBEXIT, or modifying a program line.

The ABORTIO statement can be used to prematurely terminate a transfer and free the computer. The RESET key will also terminate any active transfers, but ABORTIO is preferred.


Outbound TRANSFER

An outbound transfer has the form:

TRANSFER @Buff TO @Non_buff

If another outbound TRANSFER statement is executed while an outbound TRANSFER is occurring, HTBasic waits for completion of the first before starting the second. Any EOT/EOR events caused by the first transfer will then be logged and may be serviced before the next program line.


Inbound TRANSFER

An inbound transfer has the form:

TRANSFER @Non_buff TO @Buff

If another inbound TRANSFER statement is executed while an inbound TRANSFER is occurring, HTBasic waits for completion of the first before starting the second. Any EOT/EOR events caused by the first transfer will then be logged and may be serviced before the next program line.


STATUS, CONTROL, READIO, and WRITEIO

I/O paths and many device interfaces have registers that control aspects of their operation and report their status. For example, screen colors can be controlled by writing to the registers of the CRT interface. The baud rate can be changed by writing to the registers of the serial interface. The status of an I/O path variable can be read from the I/O path registers. These and many other attributes can be controlled and read through interface registers.

In general, there are three different kinds of registers: I/O path registers, interface registers, and hardware registers. The following program shows access to all three types:

10    ASSIGN @Path TO 9
20    PRINT "I/O Path  Register 0:",STATUS(@Path,0)
30    PRINT "Interface Register 0:",STATUS(9,0)
40    PRINT "Hardware  Register 0:",READIO(9,0)

The CONTROL and STATUS statements are used to access two of the three kinds of registers: I/O path registers and interface registers. If the statement specifies an I/O path, I/O path registers are accessed. If the statement specifies an interface select code, interface registers are accessed.

The range of legal register numbers and their definitions differ depending on the I/O path assignment or the type of interface. I/O path registers are given below. The registers for each interface are given in the chapters that follow this one, or the documentation that came with the interface.


CONTROL Statement

The CONTROL statement sends control information to an interface or an I/O path control register. Information is sent by specifying a starting register number, and a value to be sent to that register. If it is not specified, the starting register number is zero. If you specify more than one data value, the register number is incremented by one after sending each value. For example:

CONTROL 2;Column,Line

sends the value of the variable Column to register zero on interface number two and the value of the variable Line to register one.


STATUS Statement and Function

The STATUS statement and STATUS() function return control information from an interface or an I/O Path status register. Using the STATUS statement, the values of several status registers are copied into a list of numeric variables, starting at the specified register number and continuing until the variable list is exhausted. If it is not specified, the starting register number is zero. For example:

STATUS 2;Column,Line

gets the value of status register zero on interface number two and stores it into the variable Column and then it gets the value of status register one and stores it into the variable Line.

The STATUS() function complements the STATUS statement. It allows immediate access to a single register without need for a temporary variable or separate STATUS statement. However, the STATUS() function can only return the value of one register at a time, while the STATUS statement can return the values of multiple registers in a single statement.

The CONTROL and STATUS registers for I/O paths assigned to devices, files, pipes, and buffers are described in the following paragraphs.


Device I/O Path Registers

No CONTROL registers exist for I/O paths assigned to devices. The STATUS registers for I/O paths assigned to devices are:

0 - ASSIGN status: 0 - not assigned, 1 - assigned to a device.
1 - The interface select code.
2 - Number of devices.
3 - Device selector of device 1.
4 - Device selector of device 2 (if two or more devices are present).
n+2 - Device selector of device n (if n or more devices are present).


ASCII File I/O Path Registers

No CONTROL registers exist for I/O paths assigned to ASCII files. The STATUS registers for I/O paths assigned to ASCII files are:

0 - ASSIGN status: 0 - not assigned, 2 - assigned to a file.
1 - File type: 3 - ASCII file.
2 - Always 4.
3 - Number of records. DOS, Windows, and NT files are extendible and
    so the number of records can be more or less than the number given
    in the CREATE statement for the file.
4 - Record size: 256 bytes.
5 - Current record.
6 - Current byte within record.


BDAT and Ordinary file I/O Path Registers

For I/O paths assigned to BDAT and ordinary files, all registers can be read with the STATUS command. Only registers greater than 4 can be set with the CONTROL command. Ordinary files are listed by CAT with a blank file type or the name of the operating system ("DOS" or "HP-UX").

0 - ASSIGN status: 0 - not assigned, 2 - assigned to a file. A DOS device looks like a file to HTBasic when assigned using its DOS name.
1 - File type: 2 - BDAT file, 4 - ordinary file.
2 - Always 4.
3 - Current number of records. With DOS, Windows, NT, and UNIX,
    file lengths are extendible, so the number of records can be more or
    less than the number given in the CREATE. If the last record is only
    partially filled, it is still counted.
4 - Record size. For ordinary files, the record length is always 1.
5 - Current record.
6 - Current byte within record.
7 - EOF record.
8 - Byte within EOF record.

EOF record and byte define the position of the first byte after the last byte in the file.


BUFFER I/O Path Registers

All registers can be read with the STATUS command. The following registers can be set with the CONTROL command: 3, 4, 5, 8, and 9.

0 - ASSIGN status: 0 - not assigned, 3 - assigned to a buffer.
1 - Buffer named flag: 1 - named, 2 - unnamed.
2 - Buffer size in bytes.
3 - Current fill pointer.
4 - Current number of bytes in buffer.
5 - Current empty pointer.
6 - Interface select code for in-coming TRANSFER.
7 - Interface select code for out-going TRANSFER.
8 - Continuous in-coming TRANSFER flag: zero - not continuous,
    non-zero - continuous.
9 - Continuous out-going TRANSFER flag: zero - not continuous,
    non-zero - continuous.
10 - In-coming TRANSFER status.

Bit	Value	Meaning
7	128	Always 0
6	64	Active
5	32	Aborted
4	16	Error
3	8	Device caused termination
2	4	Byte count caused termination
1	2	Record count caused termination
0	1	Match char caused termination

11 - Out-going TRANSFER termination status. Same meaning as above.
12 - Count of bytes transferred by last in-coming TRANSFER.
13 - Count of bytes transferred by last out-going TRANSFER.


Pipe I/O Path Registers

No CONTROL registers exist for I/O paths assigned to pipes. The STATUS registers are:

0 - ASSIGN status: 0 - not assigned, 4 - assigned to a pipe.
1 - Always 1.
2 - Read/write flag: 0=ENTER, 1=OUTPUT, 2=ENTER/OUTPUT.
100 - Child process ID.


Interface Hardware Registers

Accessing hardware registers can cause your system to crash, data to be lost, or damage to your hardware. TransEra cannot be held responsible for any consequences. If you need technical assistance from TransEra, it will be provided at the current consulting rates.

The READIO and WRITEIO statements allow an HTBasic program to directly manipulate the interface hardware and physical memory locations. The hardware register numbers and their definitions are dependent on the actual hardware. The level of access to the computer hardware is also dependent on operating system protection methods. Do not mix READIO and WRITEIO operations with STATUS and CONTROL operations. In general, you are better off using STATUS and CONTROL operations and avoiding READIO and WRITEIO.


READIO Function

The READIO function returns the contents of a hardware register of an interface. The value of the first argument specifies an interface select code and a valid interface register number is specified as the second argument. That hardware interface register is read and its contents are returned. For example:

PRINT "Register=";READIO(7,1)

prints the contents of interface register number one on interface number seven.

Extensions to READIO and WRITEIO allow PEEK and POKE operations. Other extensions allow the address of a numeric variable to be read, and assembly language subroutines to be called. All these extensions are explained later in this chapter.


WRITEIO Statement

The WRITEIO statement writes a data value to an interface hardware register. If a valid interface select code and interface register number are specified, then the data value is written to the hardware interface register. For Example:

WRITEIO 7,3;Regdata

writes the value of the variable Regdata to register number three on interface number seven. Again, extensions to READIO and WRITEIO are explained below.


PEEK/POKE Memory

The number 9826 is used to specify a peek or poke operation in a READIO or WRITEIO statement. If positive, a byte operation is done; if negative, a word operation is done. These combinations are shown in the table below. L specifies the address of the byte or word. If you specify a word operation and L is odd, the even address L-1 is used. V specifies the value to store into memory.

READIO(9826,L)	PEEK byte
READIO(-9826,L)	PEEK word
WRITEIO 9826,L;V	POKE byte
WRITEIO -9826,L;V	POKE word

Under the DOS Version, L specifies a linear process address, not a physical address. To peek/poke the first megabyte of physical memory, use 8452 instead of 9826. Note the warning below.

Under Windows and NT, L specifies an address within the HTBasic process.

Under UNIX, L specifies an address within the HTBasic process. The special interface select code 8452 should be used instead of 9826 to peek physical addresses rather than process addresses. Peeking physical memory is only possible if the /dev/mem device is readable by the HTBasic process. Note the following warning.

WARNING: Use PEEK and POKE only on addresses returned by READIO(9827,I)! Using other locations can cause your system to crash, data to be lost, or damage to your computer hardware. Use of this function for any other address is unsupported, and TransEra cannot be held responsible for any consequences.


IN/OUT Operations

At the lowest level, the CPU in your computer must be able to input or output data. Some CPU's, like the Motorola 680x0 processors in an HP Workstation, use memory space for all CPU I/O, even for devices. Other CPU's, like the Intel 80x86 processors in a PC, have an I/O space in addition to memory space. PEEK/POKE access memory space; IN/OUT access I/O space. The following four statements are available in HTBasic to access I/O space.

INP(L)	IN byte
INPW(L)	IN word
OUT L,V	OUT byte
OUTW L,V	OUT word

L specifies the address of the byte or word. V specifies the value to read or write. IN/OUT operations are most typically used to access a data acquisition board plugged into your computer for which there is no HTBasic driver. Most boards come with example programs showing how to access them with IN/OUT instructions.

WARNING: Because incorrect use of IN and OUT can cause your system to crash, data to be lost, or damage to your computer hardware, use this function at your own risk. TransEra cannot be held responsible for any consequences.


Locating a Numeric Variable

READIO(9827, variable-name ) is used to locate a numeric variable or an element of an array. This operation is useful in connection with assembly language subroutines because it allows you to identify the starting address of the subroutine so that the subroutine may be called with the WRITEIO statement.

10 INTEGER A(0:5)
20 Address = READIO(9827,A(0))
30 PRINT "The address of A(*) is ";Address


Calling Assembly Language Subroutines

WRITEIO Proc,L;V can be used to call an assembly language subroutine. L specifies the address of the routine to call. The value V is loaded into the main accumulator. The value of Proc depends on the version of HTBasic you are running. A detailed explanation of calling assembly language subroutines is given in Chapter 14, "Mixed Language Programming."


Interrupts

Interrupts allow the computer to perform other tasks while you wait for some condition to occur. This eliminates the need to continually monitor for some event.


ON INTR Statement

The ON INTR statement defines an event branch to be taken when an interface card generates an interrupt. You specify the interface select code, an optional priority and the branch type. The branch type may be either a GOTO, GOSUB, CALL, or RECOVER. For example:

ON INTR 7,4 GOSUB Repair

When an interrupt occurs a DISABLE INTR for the interface is automatically executed. Consequently, an ENABLE INTR statement must be used to explicitly re-enable interrupts.

The default priority is one. The highest priority that can be specified is fifteen. ON END, ON ERROR, and ON TIMEOUT have a higher priority than ON INTR. When an INTR initiated branch is taken with a GOTO the system priority is not changed. When an ON INTR branch specifies a CALL or GOSUB the system priority is changed to the specified priority.

RECOVER causes the program to SUBEXIT from contexts as needed to return to the defining context and resume execution at the specified program line. ON INTR statements that specify CALL or RECOVER will be serviced even if the program context has been changed to another subprogram. ON INTR statements that specify GOTO or GOSUB will be logged and then serviced when control returns to the defining program context.

ON INTR is canceled by OFF INTR, disabled by DISABLE or DISABLE INTR.


OFF INTR Statement

The OFF INTR statement cancels event branches defined by ON INTR. Any INTR events that have been logged but not yet serviced are canceled. An OFF INTR statement without the optional interface select code disables event-initiated branches on all devices. If the interface select code is specified only that interface interrupt will be disabled. For example:

OFF INTR 7

cancels event branches for the IEEE-488 interface.


Enabling and Disabling Interrupts

The DISABLE statement disables all defined event branches except END, ERROR, and TIMEOUT. While disabled, the first event of each type that occurs, is logged. When event branching is re-enabled with the ENABLE statement, all logged events are serviced in the order of their event priorities.

The DISABLE INTR Statement disables interrupts from just the specified interface. For example:

DISABLE INTR 7

disables interrupts from the IEEE-488 interface.

The ENABLE INTR statement enables interrupts from a specified interface. An optional bit mask is stored in the interface interrupt-enable register. The default bit mask is the previous bit mask for that interface, or if there is no previous bit mask then a bit mask of all zeros is used. The meaning of the bit mask depends on the interface; consult the interface documentation. For example:

ENABLE INTR 9;1

enables interrupts on the RS-232 interface and stores one into the interface interrupt-enable register. For the serial interface, one happens to mean "interrupt when a character is received."


Interrupt Routines

When an interrupt occurs, the event handler would typically perform the following steps: 1) find out what action needs to be taken, 2) perform the needed action, 3) perform whatever interface specific action is necessary to acknowledge the interrupt, 4) re-enable interrupts with the ENABLE INTR command. The following example shows the typical sequence of statements used for interrupt set up and handling:

1    REM TERMINAL.BAS
10   ON KBD CALL To_modem
20   ON INTR 9 CALL From_modem       !Tell BASIC to interrupt
30   ENABLE INTR 9;1                 !Tell interface to interrupt
40   LOOP
50     DISP TIME$(TIMEDATE)          !Now free to do something
60   END LOOP                        !while you wait
70   END
80   SUB From_modem
90     WHILE BINAND(STATUS(9,10),1)
100      PRINT CHR$(STATUS(9,6));    !Interface dependent ack.
110    END WHILE
120    ENABLE INTR 9;1               !re-enable the interrupt
130  SUBEND
140  SUB To_modem
150    OUTPUT 9;KBD$;
160  SUBEND


Specialized I/O Statements

In addition to the general I/O statements explained above, several statements are provided for specialized I/O. PRINT, DISP, INPUT, and LINPUT allow specialized I/O with the CRT or keyboard. They are explained in Chapter 8, "CRT and Keyboard." The PRINT statement can also be redirected to a printer. READ and DATA allow data to be stored within the BASIC program itself. BEEP allows tone generation on computers with the necessary hardware.


READ/DATA Statements

The READ statement is quite similar to the INPUT statement. However, the values are read from DATA statements instead of the keyboard. DATA statements contain string and/or numeric constants separated by commas. This provides a convenient method of embedding known data that your program requires, right in the program itself. The first READ statement in a context reads the first DATA statement in that context. Each READ statement thereafter maintains a DATA pointer that moves to the next item after each is read from the DATA statement. The DATA pointer can be reset to the beginning of any DATA statement in the context with the RESTORE statement.

READ statements can be useful for initializing the values of several program variables more compactly than with individual [LET] assignment statements. It is also handy for table data that you can READ into an array.

The following example shows the use of the DATA, READ and RESTORE statements.

100  DATA 1,2,"STRING CONSTANT",10
110  READ A,B,A$,C       ! read data from line 100
120  DATA 13,24,36,42,59
130  DIM D(4),E(4)
140  READ D(*)           ! read array data from line 120
150  MAT D=D*(B)
160  RESTORE 120
170  READ E(*)           ! read data from line 120 again
180  END

Note that line 160 specifies line 120 as the data statement to be restored since there is a previous data statement in line 100. If line 120 were the first data statement in the program, line 160 could be simply RESTORE with no line number.


BEEP
BEEP Statement

BEEP is a statement used to play music or tones by producing notes of a certain frequency and duration. On machines that do not support variable frequency sound generation, this statement rings the terminal bell. HP BASIC rounds the frequency value to a multiple of 81.38 Hz and supports a range of 81 Hz to 5.208 KHz. The rounding and range for each version of HTBasic is given later in this section.

10   REM -- MUSIC.BAS - Print table of musical notes.
20   REM -- Also play C-major scale.
30   A4=440                            ! Frequency of the reference note
40   R=2^(1/12)                        ! One octave doubles the frequency,
                                         12 half-steps in octave
50   C4=A4/(R^9)                       ! Scale goes from C to B
60   DATA C,C#,D,D#,E,F,F#,G,G#,A,A#,B
70   DIM Name$(11)[2]
80   READ Name$(*)
90   N=C4/8                            ! start at C1
100  CLS                               ! clear the screen
110  FOR Octave=1 TO 7
120      Col=1+(Octave-1)*11
130      PRINT TABXY(Col,1);"Note  Freq|";
140      PRINT TABXY(Col,2);"----------+";
150      FOR Note=0 TO 11
160          OUTPUT A$ USING "3A,X,4D.D,#";
             Name$(Note)&VAL$(Octave),N
170          PRINT TABXY(Col,Note+3);A$;"|"
180          IF Octave>1 AND LEN(Name$(Note))=1 THEN BEEP N,.25
190          N=N*R
200      NEXT Note
210      PRINT TABXY(Col,15);"----------+";
220  NEXT Octave
230  BEEP N,.5 ! complete the last scale
240  END

This example demonstrates the BEEP statement, while also producing a useful table. The program plays C Major scales for octaves two through seven. At the same time, it prints a table of musical notes and their associated frequencies. The frequencies printed are for the Equal Tempered Chromatic Scale adopted by the American Standards Association in 1936. The "A" note in the fourth octave (A4) is the reference note and has a value of 440 Hertz. An increase of one octave, to A5 doubles the frequency, while moving down one octave halves the frequency. Twelve half-steps compose an octave and are equally spaced geometrically (rather than arithmetically). That is, the ratio of frequencies between any two adjacent notes is a constant.

Another standard that exists uses A4=435. This was an International standard adopted in 1891. The program is easily modified to show this scale. Change the value 440 in line 30 to 435. Other modifications could change the base of the scale from "C" to something else, or change the number of notes in a scale.


PC Usage Notes

On the IBM PC, the period (not the frequency) is rounded to a multiple of 0.838 micro-seconds. The range of frequencies is 40.7 Hz to 32.767 KHz.


UNIX Usage Notes

The -beep command line switch determines whether the BEEPstatement uses the console to produce the tone, or whether it uses the CRT driver to produce the tone (in some driver-specific manner). By default, the console is used to produce the tone. This is not always the appropriate behavior, as would be the case when running remotely.

On the Sun Version, the console uses the /dev/audio device to produce the tone. The period is rounded to a multiple of 125 micro-seconds. Consequently, the number of frequencies is very limited. For example, above 1000 Hz the only frequencies available are 1143, 1333, 1600, 2000, 2667, and 4000.

If the X Windows CRT driver is producing the tone, then the results vary according to the X Server. OpenWindows 2.0 always produces a tone of 2400 Hz, although the duration of the BEEP statement matches the duration specified. HP-VUE produces the requested frequency, but allows the program to continue immediately while the tone is sounding.


CRT, Keyboard, and Printer
 Chapter 8
CRT, Keyboard, and Printer

This chapter discusses I/O (input/output) facilities for the screen and keyboard. The general I/O statements presented in Chapter 7 are given, as well as special statements for display, keyboard, and printer support. Controlling various attributes of the screen and keyboard, including screen colors, is explained. Finally, tables of the CRT and KBD registers are given.


Display (CRT)

The CRT is the display on your computer. CRT stands for Cathode Ray Tube and is often used as a synonym for display, even when the display is not a tube. Several display adapters are supported by HTBasic. Each type requires a device driver. When HTBasic starts, it automatically picks a CRT driver. The -CRT command line switch can be used to select a different driver. The PLOTTER IS statement can be used to load additional drivers or change to a driver that is already loaded. The Installing and Using manual, Chapter 3, "CRT and Graphic Drivers" explains how to use these features.

The interface select code (ISC) of the CRT is permanently set to 1. This ISC is used so often, a special function, CRT, can be used to return the value 1, while providing a mnemonic for the ISC.

OUTPUT CRT;"Hello World"
ASSIGN @Output TO CRT


Display Organization

As explained in Chapter 1, "Getting Started," the computer display is organized in a very particular way by HTBasic. Different statements affect different parts of the display. To display information in the output area, use the OUTPUT or PRINT statements. To display information on the Display Line, use the DISP statement. The Input Lines show the information the user types in response to queries by your programs. Information can be pre-loaded into the Input Lines by using OUTPUT KBD. The message line shows various system messages as well as live keyboard calculator results. The softkey menus display the current softkey macros unless an ON KEY is active, in which case the ON KEY LABEL overwrites the softkey macro for that key. Each of these areas of the screen are discussed in more detail through out this chapter.


OUTPUT CRT

The OUTPUT CRT statement sends information to the output area of the screen. OUTPUT CRT uses rules consistent with OUTPUT to other devices and is useful for verifying I/O program correctness. However, the PRINT statement is often better suited for screen output.


PRINT

The PRINT statement is provided to allow easy printing of information on the screen or to a printer. By default, PRINT output goes to the screen, but the PRINTER IS statement can be used to redirect output from the PRINT statement to a printer, device, or file. The PRINTER IS statement can also set the width at which output should wrap, and the characters that should be sent at the end of a line. These features allow easy use of many different printers.


DISP Statement

The DISP statement is very similar to the PRINT statement. However, DISP output goes to a part of the screen known as the display line. When the semicolon is used to end display output, the display line will scroll to the left if output goes off the right end of the display line. Most other aspects of the DISP statement match those of the PRINT statement.


PRINT and DISP Statements

With both PRINT and DISP, if you separate arguments in a print list with commas, they will be printed in columns. The columns are ten characters wide. If you want "compressed" format, substitute a semicolon in place of the comma. In compressed format, numerics are printed with one additional trailing space and strings are printed with no additional spaces. You may also end a print list with a semicolon to suppress the usual CR/LF that forces a new line. Then you can continue output on the same line with another PRINT statement. If the default PRINT/DISP formats are not acceptable, USING can be specified to format the data as desired.

Numbers are printed with twelve significant digits. If the number is outside the range 1E-4 and 1E+6 then the number is printed in scientific notation. If the number is positive, it is always preceded by one space, even in the compressed format. If it is negative, the negative sign is printed in place of the leading space.

Complex numbers are printed in rectangular form, first the real part, then an extra space, and finally the imaginary part. The real and imaginary parts are printed using the print rules given in the previous paragraph.

You can position text on the screen with TAB(column) and TABXY(column,row). The left-most column is column one, and the top-most row is row one. TAB can also be used on a printer; TABXY can only be used on the screen. The following example illustrates use of TABXY.

10  ! Display time in upper-right corner of screen for 30 seconds
20    St=TIMEDATE ! start time
30    REPEAT
40      PRINT TABXY(70,1);TIME$(TIMEDATE)
50    UNTIL TIMEDATE>St+30
60    END

A full array can be printed by using the array name with a full array specifier. The elements are printed in row major order, and in fields determined by the punctuation following the array.


Attributes and Colors

Various control characters can be included in PRINT or OUTPUT CRT strings. These control characters allow simple cursor movement as well as selection of colors and attributes.

Character	Meaning
CHR$(7)	Rings the bell.
CHR$(8)	Moves the print cursor back one space.
CHR$(10)	Moves the print cursor down one line.
CHR$(12)	Prints two line-feeds, scrolls the extended output area
buffer so that the next item goes to the top of the CRT.
CHR$(13)	Moves the print cursor to column one.

Character	Meaning
CHR$(128)	All attributes off.
CHR$(129)	Inverse mode on.
CHR$(130)	Blinking mode on.
CHR$(131)	Inverse and Blinking modes on.
CHR$(132)	Underline mode on.
CHR$(133)	Underline and Inverse modes on.
CHR$(134)	Underline and Blinking modes on.
CHR$(135)	Underline, Inverse, and Blinking modes on.

Character	Meaning
CHR$(136)	White
CHR$(137)	Red
CHR$(138)	Yellow
CHR$(139)	Green
CHR$(140)	Cyan
CHR$(141)	Blue
CHR$(142)	Magenta
CHR$(143)	Black

The characters from 128 through 143 conflict with International language characters. To resolve the conflict, the CONTROL CRT,100;1 statement moves this range down to 16 through 31. CONTROL CRT,100;0 moves the range back up to 128 through 143.

Not every attribute is available on every display system. Run the following example on your computer to find out what attributes are supported by your system.

10   REM -- ATTRIB.BAS - Run this program to see what
20   REM -- attributes are supported by your system.
30   INTEGER I
40   DIM A$[40]
50   DATA No Attributes,Inverse,Blinking,Inverse and Blinking,Underline
60   DATA Underline and Inverse,Underline and Blinking
70   DATA "Underline, Inverse, & Blinking"
80   CLEAR SCREEN
90   PRINT "Attributes"
100  FOR I=128 TO 135
110    READ A$
120    PRINT CHR$(I);"CHR$(";I;") ";A$
130  NEXT I
140  PRINT CHR$(128);TABXY(50,1);"Colors"
150  FOR I=136 TO 143
160    PRINT TABXY(50,I-134);CHR$(I);"CHR$(";I;")"
170  NEXT I
180  PRINT CHR$(136);
190  END


Display Functions

It is possible to disable the effect of the attribute characters just described, displaying them instead of executing them. This is useful when debugging OUTPUT. The DISPLAY FUNCTIONS ON statement causes all control characters to be displayed but not executed. The only exception is carriage return, CHR$(13), which is first displayed and then the print cursor is moved to column one of the next line. DISPLAY FUNCTIONS OFF returns execution of attribute characters to normal.

This function is the equivalent to pressing the DISPLAY FCTNS key, or to executing the CONTROL CRT,4 statement.


CRT Related Statements

There are several statements that affect the CRT. Consult the Reference Manual or use the HELP statement to obtain more information on each of these statements.

Statement	What It Does
ALPHA ON/OFF	Controls ALPHA screen visibility
ALPHA HEIGHT	Sets the number of lines in ALPHA screen
ALPHA PEN	Sets the ALPHA display color
CLEAR LINE	Clears the keyboard input line
CLEAR SCREEN	Clears the ALPHA display
CLS	Abbreviation for CLEAR SCREEN
DUMP ALPHA	Prints the contents of the ALPHA display
GRAPHICS ON/OFF	Controls graphics screen visibility
KBD LINE PEN	Sets the color of the input line.
MERGE ALPHA	Enables all planes for Alpha and Graphics
PRINT PEN	Sets the output area and display line color
RUNLIGHT ON/OFF	Controls Run Indicator Visibility
SEPARATE ALPHA	Simulates independent alpha and graphics

These statements affect the softkey menus:

Statement	What It Does
EDIT KEY	Edits a softkey macro
KBD CMODE ON/OFF	Changes softkey labels to match HP keyboards
KEY LABELS ON/OFF	Controls the display of the softkey labels
KEY LABELS PEN	Sets the color for the softkey labels
LOAD KEY	Loads softkey macros from a file
ON/OFF KEY	Defines an event branch for a softkey
SCRATCH KEY	Deletes softkey macros
SET KEY	Defines one or more softkey macros
SYSTEM KEY	Displays the System Softkeys Menu
USER KEYS	Displays the specified User Softkey Menu

More should be said concerning screen colors.  Let's assume you wish to set the screen color to green instead of white. Which of these statements do you use?

ALPHA PEN 4
ALPHA PEN 139

If you are using a bit-mapped display driver (CRTB), then regular pen numbers are used so the first statement is correct. If you are using an alpha (non-bit-mapped) display driver (CRTA), then the pen numbers match those used with CHR$(), so the second statement should be used. More on display drivers is given in the Installing and Using manual. Suffice it to say that CGA and Hercules displays use the CRTA driver and other displays usually use the CRTB driver.


CONTROL/STATUS CRT

The CONTROL CRT statement can be used to control various CRT attributes, while the STATUS CRT can be used to read the status of those attributes. A complete list of the CONTROL and STATUS registers for the CRT is given at the end of this chapter. The following is an example:

10    ON CYCLE 1,15 CALL Time
20    LOOP
30      PRINT TABXY(RND*68+1,RND*(STATUS(CRT,13)-8)+1);CHR$(32+RND*96);
40    END LOOP
50    END
60    SUB Time
70      STATUS CRT,0;Col,Row
80      CONTROL CRT,0;70,1
90      PRINT TIME$(TIMEDATE);
100     CONTROL CRT,0;Col,Row
110   SUBEND

In this example, each time the SUB "Time" is called, the print position is remembered, the time is written in the upper-right-hand corner of the screen, and then the print position is restored. Line 10 causes the sub to be called once a second. Lines 20 to 40 are just to keep the program doing something, to demonstrate the updating of the time. These lines could be deleted and replaced with whatever program you wish. Notice in line 30 the function form of STATUS and in line 70, the statement form.


ENTER CRT

ENTER CRT enters information from the CRT screen just as if it had been sent to the computer from some external device. The present print position is the source of the data and is updated as data is entered. Trailing spaces on a line are ignored. The last character on the line is a line-feed (LF) with an EOI signal.

10 PRINT TABXY(1,1);"HELLO!";TABXY(1,1);
20 ENTER CRT;A$

The string variable A$ is assigned "HELLO!"


Keyboard (KBD)

The interface select code (ISC) of the keyboard is permanently set to 2. This ISC is used so often, a special function, KBD, can be used to return the value 2, while providing a mnemonic for the ISC.

ENTER KBD;A$
ASSIGN @Input TO KBD


ENTER KBD

ENTER KBD reads information from the keyboard. The INPUT and LINPUT statements also read information from the keyboard but are designed especially for the keyboard and provide some features not supported by ENTER. The number builder rules are not the same for the two. ENTER KBD uses rules consistent with ENTER from other sources and is useful for verifying I/O program correctness. Toward this end, an EOI signal can be generated from the keyboard by entering a control-E before the character to be sent with the EOI signal. This pseudo-EOI must be enabled with CONTROL KBD,12;1. No keystrokes are entered into ENTER items until either a CONTINUE key or ENTER key is pressed. If CONTINUE is pressed, the present keyboard buffer is transmitted through the I/O path to the ENTER statement with no appended characters. If ENTER is pressed, the buffer is transmitted with CR/LF appended to the buffer.


INPUT Statement

The INPUT statement allows the user to assign a value to a variable by typing in the value on the keyboard. A prompt is displayed on the display line. The INPUT statement can specify the prompt, or a question mark (?) will be used by default. To suppress the prompt, specify a prompt string of "".

The input statement can input values for simple variables, full arrays, array elements, or sub-strings. A full array name must be followed by the full array specifier, "(*)". Values for the array must be entered in row major order.

Leading and trailing spaces are ignored. Data values may be entered individually or multiple values may be entered at once. If multiple values are entered, separate each value with a comma. If too many values are entered, the extra values are ignored. Both quoted and unquoted strings are allowed. Commas are not allowed in unquoted strings, but may appear in quoted strings. To embed one quotation mark in a quoted string, type in two quotation marks at the place you wish to have one appear.

Two consecutive commas cause the corresponding variable to retain its old value. Terminating an input line with a comma or pressing CONTINUE or ENTER without entering any data retains the original values for all remaining variables in the list.

Let's look at a simple program to INPUT a value and assign it to a variable and then examine how to improve it.

10 DISP "Enter a file name";
20 INPUT F$
30 END

Now let's see how to do this in just one statement:

10 INPUT "Enter a file name: ",F$
20 END

To provide a default answer we might do the following:

10 F$ = "STUDENT.DAT"
20 INPUT "Enter a file name <STUDENT.DAT>: ",F$
30 END

If the default answer is OK with the user, he need only press ENTER to accept the default. If it is not OK, he can enter the proper value. Of course, this behavior would need to be documented somewhere in the instructions given to the user.


LINPUT Statement

The LINPUT statement differs slightly from the INPUT statement. Only one value can be input with each LINPUT statement, the variable must be a simple string, string element, or sub-string. All characters typed, including commas and quotation marks, are stored in the variable. Only the end-of-line character will delimit the data.


OUTPUT KBD

OUTPUT KBD sends keystrokes to the keyboard buffer, just as if someone had typed them. This can be useful in giving the user a default response for INPUT that she can edit:

10   OUTPUT KBD;"STUDENT.DAT";
20   INPUT "Enter a filename:",F$
30   END

Function keys can be simulated by sending the two character sequences to the KBD device. The first character is a CHR$(255). This value is followed by a character that specifies the function key. A table giving the second character codes is found in the Installing and Using manual.

10    OUTPUT KBD;"""AUTOST File Complete"""&CHR$(255)&"E";
20    WAIT 1
30    OUTPUT KBD;CHR$(255)&"!"&"SCRATCH"&CHR$(255)&"E";
40    END

The first line in this example shows how to display your own messages on the message line. The ENTER key is output to the keyboard with the two characters, CHR$(255)&"E". The semicolon at the end of the line prevents carriage-return/line-feed characters from being sent to the keyboard. Line 30 is a handy line to execute at the end of your AUTOST file. The CHR$(255)&"!" characters are the STOP key, followed by a SCRATCH statement. This will cause your AUTOST file to be SCRATCHed from memory after it is executed.

The CHR$(255) character displays as a reverse-video "K" on an HP BASIC Workstation. On other computers, it displays differently. PCs using standard PC character sets (code pages) display the character as a space. (It is possible on a PC with an EGA or VGA display to load an HP compatible character set. See Chapter 13, "International Language Support.") Sun SPARCstations, HP 700 workstations, and X terminals using the Latin-1 character set display the character as ÿ, lowercase y umlaut or diaeresis. The glyph displayed for CHR$(255) by HP 700 workstations using the Roman8 character set is undefined.


CONTROL/STATUS KBD

The CONTROL KBD statement can be used to control various keyboard attributes, while the STATUS KBD can be used to read the status of those attributes. A complete list of the CONTROL and STATUS registers for the keyboard is given at the end of this chapter. The following is an example:

CONTROL KBD,16;1

This register disables all scrolling keys. This is useful if you have displayed a screen image that you wish to prevent the user from scrolling off the screen.


Using a Printer

The printer is usually accessed differently under DOS than under UNIX. Under DOS, the printer is usually accessed directly, as a device. While this is possible under UNIX, it is better to access the printer using the UNIX print daemon. Both these approaches are discussed below. There are several special statements that can be used with printers. These are also presented.


Accessed Directly

A printer can be handled just like any other device. To use the printer, you need to know the device selector for it. The most common device selectors for printers are 10, 9, and 701. The default device selector for the first centronix port is 10 (LPT1 on a PC). The default device selector for first serial port is 9 (COM1 on a PC). The default device selector for an IEEE-488 printer with primary address 1 is 701. These values are default values and may be different on your system if you specified different values when you loaded the interface device drivers.

100 SUB Print3(A$)    ! subprogram to support 3 printers at once
110   OUTPUT 9;A$     ! first the serial printer
120   OUTPUT 10;A$    ! next the parallel printer
130   OUTPUT 701;A$   ! last the IEEE-488 printer
140 SUBEND

This example is a subprogram for a hypothetical user who wishes to use three printers simultaneously. One printer is hooked to the RS-232 port, one to the Centronix port, and one to the IEEE-488 bus. Print3(String-expression) is used to send output to all three printers. The point is that a printer can be treated just like any other device.


Using the Print Daemon

Because UNIX is a multitasking, multiuser, networked system, access to the printer must be coordinated to prevent more than one program from intermixing printer output. It is the UNIX print daemon's job to collect printer output and manage the printer. You may send output to the print daemon through a pipe or indirectly through a file.

The command

10  ASSIGN @Prt TO "| lp"

establishes access to the printer through the print daemon, through the UNIX "lp" command, through a pipe, through the @Prt I/O path. Any I/O statement that can specify an I/O path can now output data to the printer. The print daemon collects the output until the pipe is closed:

20  OUTPUT @Prt;A$
30  ASSIGN @Prt TO *

Pipes can also be used in DUMP DEVICE IS, PLOTTER IS, PRINTALL IS, and PRINTER IS statements.

Alternatively, send output to a file and then use the EXECUTE command to send the file to the printer:

10  CREATE "TEMP.TXT",0
20  ASSIGN @Prt TO "TEMP.TXT";FORMAT ON
30  OUTPUT @Prt;A$
40  ASSIGN @Prt TO *
50  EXECUTE "lp TEMP.TXT";WAIT OFF

SunOS 4.x and HP-UX both can use the UNIX "lp" command to send output to the print daemon. Other commands may also work, such as "lpr". Check with your system administrator or check your system documentation for more information.


The PRT function

Just as the special functions CRT and KBD exist because the screen and keyboard are accessed so frequently, there exists a special function, PRT, which can be used to access the printer. One problem exists, however. The ISCs for the screen and keyboard are permanently set but the printer's is not. The printer can be hooked to any interface. Or more than one printer may be hooked up at the same time. What value, then, should PRT return. HP BASIC approaches the dilemma by assigning 701 to PRT and if your printer is anywhere else, tough luck.

HTBasic solves the dilemma by letting you change the value of PRT. By default, it is 10 on PC Versions and 701 on UNIX Versions, but you may execute a CONFIGURE PRT statement in your AUTOST file to change the value if needed. PRT can only assume a numeric value; it is not possible to assign a pipe or file to PRT. As shown in the Print3 example above, you don't have to use the PRT function to output to a printer. It is available as a convenience only.

10 PRINTER IS PRT
20 PRINT "PRT = ";PRT
30 END

This example prints the value of PRT to the printer. PRT, KBD, and CRT are just ordinary functions, and can be used anywhere a normal function is used.


The PRINTER IS device

The CAT, LIST, PRINT, and XREF statements send output to the "PRINTER IS" device. By default this is the CRT, but it can be changed with the PRINTER IS statement to a printer (or any other device), a file, or a pipe. Thus, screen output produced by these statements can easily be redirected to your printer.

The PRINTER IS statement has facilities for adapting printer output for various printers. The output can be set to wrap at a specified WIDTH, or wrap can be disabled altogether. The characters sent at the end of a line (EOL), CR/LF by default, can be changed to match that expected by your printer. The PRINTER IS statement can even specify that EOI be sent with the EOL for IEEE-488 printers. Many older printers lose characters sent while the printer is returning the carriage. This character loss can be prevented by specifying a delay after an EOL sequence.

When PRINTER IS is set to a file, the file is opened and the previous contents of the file are discarded. To append to the file rather than replace the current contents, use the APPEND option.

The following example program lists itself twice, once to the printer, and once to the CRT.

10 PRINTER IS 9   ! redirect output to the serial printer
20 LIST
30 PRINTER IS CRT ! back to the screen
40 LIST
50 END

The following example sends PRINT output to the UNIX print daemon through a pipe.

10  PRINTER IS "| lp"


The PRINTALL IS device

The PRINTALL IS statement is related to the PRINTER IS statement. The PRINTALL IS statement assigns a logging device for operator interaction and error messages. It works in conjunction with the print-all mode. When the print-all mode is on, all messages output to the screen (including output area, DISP line, keyboard line, and message line) are printed on the PRINTALL device. When print-all mode is off, output appears only in the normal places, and no information is sent to the PRINTALL device.

The print-all mode is toggled between on and off each time the PRT ALL key is pressed. STATUS(KBD,1) returns a 1 if print-all mode is on, and 0 if it is off. A program can turn print-all mode on with CONTROL KBD,1;1 and off with CONTROL KBD,1;0

Print-all is a powerful debugging tool. Use it in connection with TRACE to print TRACE messages about program execution. Also, certain error conditions can produce more than one line of output. Only the last message is visible on the message line. With print-all on, all the messages can be read on the PRINTALL device. The PRINTALL IS command defines where these messages are printed. Sent to a printer, PRINTALL allows permanent logging of output. The PRINTALL device is the CRT after start-up and SCRATCH A.


CRT and KBD Registers

The following tables give the CONTROL and STATUS registers for the CRT and KBD. No READIO or WRITEIO registers are available for these devices.


CRT CONTROL Registers

The following CONTROL registers are supported.

0 - Set the current Print Column. The left most column is one.

1 - Set the current Print Row (line). The output area top line is one.

2 - Set Insert/Replace Mode. 1 - insert mode, 0 - replace mode.

3 - This register is undefined in both HTBasic and HP BASIC.

4 - Set/Reset Display Functions Mode. 1 - Control characters (including attribute characters CHR$(128) to CHR$(158)) are displayed instead of executed. 0 - control characters execute normally and are not displayed. This command is equivalent to the DISPLAY FUNCTIONS statement.

5 - Set the default ALPHA screen color (automatically sets registers 15, 16, and 17). This command is equivalent to the ALPHA PEN statement. For bit-mapped displays (CRTB), specify a pen number, 0 to 15. For alpha displays (CRTA), specify a color attribute character, 136 to 143:

Value	Color
136	White
137	Red
138	Yellow
139	Green
140	Cyan
141	Blue
142	Magenta
143	Black

6 - This register is undefined in both HTBasic and HP BASIC.

7 - This register is undefined in both HTBasic and HP BASIC.

8 - Set the current print column of the display line. The left most column is one.

9 - This register is undefined in both HTBasic and HP BASIC.

10 - Set cursor visibility. 1 - cursor on. 0 - cursor off.

11 - CRT character mapping is not supported by HTBasic.

12 - Turn Softkey Menus (Function key labels) on or off.

Value	Meaning
0	Same as 2, except that when running the menus are
displayed only if an ON KEY is active in the current menu.
1	Softkey menus off. Same as KEY LABELS OFF.
2	Softkey menus on. Same as KEY LABELS ON.

13 - Set the CRT Height. Sets the number of rows on the CRT that are actually used. The number includes the softkey menus, message line, input line, display line, a blank line, and the output area. Thus a value of 9 (the minimum allowed) provides for two lines in the output area.

14 - The Display Replacement Rule is not supported by HTBasic.

15 - Set the PRINT/DISP Color. Like CONTROL 5, but only affects the output area and the display line. This command is equivalent to the PRINT PEN statement.

16 - Set the Softkey Menu Color. Like CONTROL 5, but only affects the softkey menu color. This command is equivalent to the KEY LABELS PEN statement.

17 - Set the Input Line Color. Like CONTROL 5, but only affects the input and message lines. This command is equivalent to the KBD LINE PEN statement.

18 - The ALPHA Write-enable Mask is not supported by HTBasic. Use SEPARATE or MERGE ALPHA instead.

19 - This register is undefined in both HTBasic and HP BASIC.

20 - The ALPHA Display-enable Mask is not supported by HTBasic. Use SEPARATE or MERGE ALPHA instead.

21 - Select Compatibility Display is not supported by HTBasic. Use PLOTTER IS 3 or 6 instead.

100 - Set alternate Attribute Control range. The characters in the range CHR$(128) to CHR$(143) normally control text attributes and colors. Unfortunately, some character sets, including PC code pages use this range for international character support. This register can be used to reassign the attribute and color control characters to the range CHR$(16) to CHR$(31), leaving the international characters available for display. 1 - Use the alternate range CHR$(16) to CHR$(31) for attribute control. 0 - Use the normal range CHR$(128) to CHR$(143) for attribute control. This alternate range applies only to values used with the CHR$ function. Values used with CRT registers and the ALPHA PEN, etc. statements are left unchanged.

101 - Set font size. On PC computers, this command asks the EGA/VGA BIOS for a character font of the requested height in pixels. Legal values on an EGA are 8 and 14. On a VGA, 16 is also legal. To switch back to the default font, use a value of 0.


CRT STATUS Registers

The following STATUS registers are supported.

0 - Get the current Print Column. The left most column is one.

1 - Get the current Print Row (line). The output area top line is one.

2 - Get Insert/Replace Mode. 1 - insert mode, 0 - replace mode.

3 - Get the number of lines in the extended output area that are above the top line of the screen.

4 - Get Display Functions Mode. 1 - on, 0 - off.

5 - Get the default ALPHA screen color. The value does not show changes made using registers 15, 16, 17 and CHR$() character attributes.

6 - Get the ALPHA ON/OFF flag.

7 - Get the GRAPHICS ON/OFF flag.

8 - Get the current print column of the display line. The left most column is one.

9 - Get the Screen Width.

10 - Get the cursor visibility. 1 - cursor on. 0 - cursor off.

11 - Get the CRT character-mapping-disable flag. Always a 0 in HTBasic.

12 - Return the Softkey Menus mode.

13 - Get the CRT Height.

14 - Get the Display Replacement Rule. Not supported by HTBasic.

15 - Get the PRINT/DISP Color.

16 - Get the Softkey Menu Color.

17 - Get the Input Line Color.

18 - Get the alpha write-enable mask. The write-enable mask is set by the MERGE ALPHA and SEPARATE ALPHA statements on bit-mapped displays.

19 - Get the value of ALPHA MASK. Not supported by HTBasic.

20 - Get the ALPHA display-enable mask. Not supported by HTBasic.

21 - Get the compatibility mode flag. Not supported by HTBasic.

100 - Get alternate Attribute Control range flag. 1 - Alternate range, 0 - normal range.


KBD CONTROL Registers

The following CONTROL registers are supported.

0 - Set CAPS LOCK flag. 1 - set CAPS LOCK on, 0 - set CAPS LOCK off. Under the X Windows System, this register is ignored.

1 - Turn PRINTALL mode on/off. 1 - on, 0 - off. The PRT ALL key can also be used to toggle the mode on and off. See PRINTALL IS earlier in this chapter or in the Reference Manual for an explanation of what PRINTALL mode does.

2 - Set Softkey Menu: 0 - SYSTEM Softkeys, 1 - User Softkey menu 1, 2 - User Softkey menu 2, 3 - User Softkey menu 3.

3 - Set keyboard typematic repeat interval. The value specified, multiplied by ten, gives the interval in milliseconds to wait between characters. Values of 1 to 255 give repeat intervals of 10 ms. to 2550 ms. The value 256 turns off typematic action.

On the IBM PC and compatibles, 32 discrete typematic rates are supported from 33 ms. to 500 ms. If an unsupported value is specified, the nearest supported value is used. Typematic action can not be disabled.

Note:  IBM added the ability to change the typematic rate to the AT BIOS dated 11/15/85. IBM machines with an earlier BIOS revision, and some PC compatibles may not allow it to be changed. Also, on the IBM PC and compatibles, the typematic rate (register 3) can not be changed without also affecting the typematic delay (register 4) and vice-versa. You should normally try to set both with a statement similar to:  CONTROL KBD,3;8,70. If you set only register 3, register 4 will be set to 70. If you set only register 4, register 3 will be set to 8.

Under the X Window System, the keyboard typematic repeat interval and delay before typematic action can not be changed.

4 - Set delay before typematic action starts. The value specified, multiplied by ten, gives the interval in milliseconds during which a key must be held down before typematic repeat starts for that key. Values of 1 to 255 give delays of 10 ms. to 2550 ms.

On the IBM PC and compatibles 4 discrete delays are supported: 250, 500, 750, and 1000 ms. If an unsupported value is specified, the nearest supported value is used. The note given for register 3 above applies to register 4 also.

Under the X Window System, the keyboard typematic repeat interval and delay before typematic action can not be changed.

5 - This register is undefined in both HTBasic and HP BASIC.

6 - This register is undefined in both HTBasic and HP BASIC.

7 - Disable Keyboard Interrupts:

Value	Meaning
0	Enable all keyboard keys.
1	Disable all keyboard keys but RESET key.
2	Disable RESET key only.
3	Disable all keyboard keys.

8 - This register is undefined in both HTBasic and HP BASIC.

9 - This register is undefined in both HTBasic and HP BASIC.

10 - This register is undefined in both HTBasic and HP BASIC.

11 - Knob Pulse Mode is not supported by HTBasic.

12 - Set EOI flag. 1 - If CTRL-E is entered, then EOI is sent with the next character that is entered. 0 - CTRL-E has no special meaning.

13 - Katakana mode is not supported by HTBasic.

14 - Set base softkey number. 0 - Lowest softkey will be softkey 1 (default), 1 - Lowest softkey will be softkey 0. This register has no affect with KBD CMODE ON.

15 - Turn KBD CMODE ON/OFF. A non-zero value turns KBD CMODE ON for Nimitz compatibility. The Nimitz Keyboard is the 98203 keyboard used on the 9836. It has ten function keys, and the lowest function key is 0. A zero value turns KBD CMODE OFF, ITF compatibility (the default). The ITF Keyboard is the 46020 Keyboard used on Series 300 computers. It connects to the computer using the HIL interface, has eight function keys, and the lowest function key is 1. This command is equivalent to KBD CMODE {ON|OFF}.

16 - Disable scrolling keys: UP, DOWN, PREV, NEXT, BEGIN, and END. This allows a program to freeze the screen display, not allowing the user to scroll it off. A non-zero value disables scrolling and a zero value enables it.

100 - Controls the "Program Modified" dialog received when attempting to LOAD, GED, SCRATCH, or Quit when the current program has been modified. The default is 0 or off (no dialog appears and the current program is lost). However, the standard AUTOST file enables the "Program Modified" dialog. To disable this feature, edit the AUTOST file.

202 - Controls performance tuning under Windows. The tradeoffs of increased HTBasic performance are decreased Windows response and decreased performance in other simultaneously executing Windows applications. The decreased Windows response is most noticeable as delayed response to mouse and keyboard input in all applications including HTBasic. Valid input is in the range of 0 to 32767, the default is 32. The performance gain with increasing value is non-linear, most improvement occurs in the bottom 10% of the parameter's range.


KBD STATUS Registers

The following STATUS registers are supported.

0 - Get CAPS LOCK flag. Under the X Windows System, this register is undefined.

1 - Get Print All mode state.

2 - Get Softkey Menu number.

3 - This register is undefined in both HTBasic and HP BASIC.

4 - This register is undefined in both HTBasic and HP BASIC.

5 - Get the KBD$ Buffer Overflow Flag. A one means an overflow has occurred since the last time the register was read. Reading the register sets the flag to zero.

6 - Get the softkey macro expansion overflow flag. 1-overflow. Reading this register resets it to 0.

7 - Return Keyboard Interrupt Disable Mask.

8 - Return Keyboard Language. Always 0 - US ASCII.

9 - Return Keyboard Type. Always 0 - "Other Keyboard."

10 - Return State of Shift keys at the time of the last KNOB event.

Value	Meaning
0	Neither key pressed
1	SHIFT key pressed
2	CTRL key pressed
3	Both keys pressed

11 - Get Horizontal/All Pulse Mode flags. Always 0 - horizontal-pulse mode.

12 - Get EOI flag.

13 - Get Katakana flag.

14 - Get base Softkey number. 1 - base is 0, 0 - base is 1.

15 - Get keyboard compatibility flag. 0 - ITF, 1 - Nimitz.

16 - Get scrolling disable flag. 1 - disabled, 0 - enabled.


Files
Chapter 9
Files

This chapter explains how to do input and output to files. File management commands are presented. The different file types are explained, random and sequential file access examples are given, and file formats are discussed. An example program showing how to convert from one file type to another is shown.

Chapter 7, "General Input and Output," discussed the general principles used for input/output (I/O). These principles apply to files as well as other I/O targets. In particular, use of ASSIGN, OUTPUT, ENTER, STATUS, and CONTROL were explained. If you have not yet read that chapter, you should do so before reading this chapter.

A file is a collection of data that is kept on disk rather than in the computer's memory. When the computer is turned off, the data in the computer memory is lost but the data in a file is not.


File Management Commands

Several commands are available for managing files and the file system. It should be remembered that a major difference between HTBasic and workstation HP BASIC is that HTBasic is the guest of an operating system and HP BASIC is the operating system. As a guest of an operating system, HTBasic must live by the rules established by that system.

Please see the Reference Manual for a more detailed description of each of these statements:


ASSIGN

ASSIGN is the equivalent to the OPEN command in other computer languages. It was explained in Chapter 7.

10    ASSIGN @Io TO "C:\RMB\HP-UX.BAT";FORMAT ON,RETURN S
20    IF S THEN
30      PRINT "Oops, Error";S;"opening the file"
40      PAUSE
50    END IF
60    OUTPUT @Io;"cd \hp-ux"
70    OUTPUT @Io;"kermit take hp320.tak",END
80    ASSIGN @Io TO *
90    EXECUTE "hp-ux"
100   END

This example for the DOS Version of HTBasic shows the ASSIGN command being used to access a file called "HP-UX.BAT". (The file must already exist. Use CREATE to create a new file.)  If the ASSIGN takes place correctly, then OUTPUT is used to send some data to the file. The END in the last OUTPUT causes the file to be truncated at that point. This is useful if the old file contents were longer than the new contents. Finally, "ASSIGN ... *" is used to close the I/O path associated with the @Io variable.


CAT

CAT displays a mass storage device directory (catalog of files), or PROG file subprogram information. Several options are available. A path-specifier may be included to show which device or part of a file system to catalog. The catalog may be displayed on the current PRINTER IS device, or sent to another device or a string array. A COUNT of the entries can be returned. Only the names of the files, or complete information about the files, can be selected. Header information about the file system can be displayed or suppressed. All or only part of the files can be selected for display.  For example:

CAT "*.BAS"


CHGRP and CHOWN

CHGRP and CHOWN are useful with an operating system like UNIX in which files are owned by individuals and groups. These commands allow a user with the appropriate privilege to change or assign ownership of files. These commands are not used for DOS.

CHGRP changes the group ID (GID) assigned to a file. You must belong to the specified group and be the owner of the file or be the super-user in order to change the group.

CHOWN changes the owner, or user ID (UID) assigned to a file. Under SunOS 4.x, only the super-user can change the owner of a file. Under HP-UX, to change the owner or group, you must own the file or have appropriate privileges.


COPY

COPY is used to make a copy of a file. If a file already exists with the destination name, an error is normally returned. To suppress the error the ";PURGE" option may be specified at the end of the statement. A DOS example of the COPY statement is

COPY "DATA.1" TO "A:DATA.1"

HTBasic does not support the copy of a full disk to another disk. Under DOS you can use the DOS "DISKCOPY" or "XCOPY" commands. Under UNIX, commands like "tar" and "cpio" might be used.


CREATE

CREATE is used to create a new file or directory. Although SAVE and STORE will automatically create a new file to store a program in, data files must be explicitly created before they can be used in ASSIGN, DUMP DEVICE IS, PRINTALL IS, or PRINTER IS statements.

The four forms of the CREATE statement are CREATE, CREATE ASCII, CREATE BDAT, and CREATE DIR.  The plain CREATE statement creates an ordinary file (DOS, NT, or UNIX). CREATE ASCII and CREATE BDAT create LIF ASCII or BDAT type files (more on these later).  CREATE DIR creates directories.

The CREATE command specifies the maximum number of records to allocate for the file. However, operating systems like DOS, NT, and UNIX allow the maximum size of a file to be extended anytime the maximum number of records is exceeded. On such a system, the number of records specified in the CREATE command is ignored and space for the file is allocated only as needed.

CREATE "TEMP.TXT",0
CREATE BDAT "DATA.DAT",12,34


INITIALIZE

INITIALIZE is used to format a new disk. Used on an old disk, it completely erases all previous contents of the disk.  HTBasic does not support INITIALIZE. To initialize a new LIF disk, use an HP BASIC workstation. Under DOS, use the "FORMAT" command to initialize a new DOS disk. Under Windows or NT, use the File Manager to initialize a disk. Select "Disk" and then "Format Disk...". Under SunOS 4.x, use the "fdformat" command to initialize a new SunOS floppy disk. Under HP-UX, use the "mediainit" and "newfs" commands to initialize and place a file system on a new HP-UX floppy disk.

The following PC example shows use of the EXECUTE statement to call the DOS FORMAT command:

EXECUTE "FORMAT A:"


LINK

LINK creates a new directory entry for an existing file. This is called a hard link. After creating the link, both the old name and the new name refer to the same file. For example

LINK "Existing" TO "New" ;PURGE

LINK atomically creates a new link (directory entry) for the existing file and increments the link count of the file by one. If the new directory entry already exists, an error is given unless the PURGE option is included.

With hard links, both files must be on the same file system. Both the old and the new link share equal access and rights to the underlying object.

Because a LINK merely establishes a second name for a single file, operations on that file are effective for all the links to the file. In other words, if the file is changed using one of the filenames, the changes are visible through all the other filenames linked to that file. (Note that this general rule is true in all cases under HTBasic, but is not true under HP BASIC for RE-STORE and RE-SAVE.)

Under DOS, this command returns an error. LINK is only supported by operating systems that allow multiple links (directory entries) to a single file.


LOCK and UNLOCK

LOCK/UNLOCK are used to secure (or release) a file for exclusive use. These commands are designed for use on multitasking or network systems to prevent two users or two processes from using the same file at the same time, preventing them from making conflicting transactions. Some DOS networks require that the DOS "SHARE" command be installed before files can be shared or locked.

10    ASSIGN @Path TO "airline.seats"
20    ASSIGN @Travelagency TO 705
30    ENTER @Travelagency;Requested
40    REPEAT
50      LOCK @Path;CONDITIONAL Notlocked
60      Locked= NOT Notlocked
70    UNTIL Locked
80    ENTER @Path;Available,Booked
90    IF Requested>Available THEN
100     UNLOCK @Path
110     OUTPUT @Travelagency;"Only ";Available;" available"
120   ELSE
130     RESET @Path
140     Available=Available-Requested
150     Booked=Booked+Requested
160     OUTPUT @Path;Available,Booked
170     UNLOCK @Path
180     OUTPUT @Travelagency;"OK"
190   END IF
200   ASSIGN @Path TO *
210   END


MASS STORAGE IS

MASS STORAGE IS and the abbreviation, MSI, allow you to specify the device and path specifier to be used by default when no explicit device and path specifier are given. For example, a CAT command, without a path specifier will display files from the default path specifier. As another example, under DOS these two program fragments ASSIGN the same two files:

10  REM fragment one            10 REM fragment two
20  MSI "A:"                    20 ASSIGN @File1 TO "A:FILE1"
30  ASSIGN @File1 TO "FILE1"    30 ASSIGN @File2 TO "B:FILE2"
40  MSI "B:"
50  ASSIGN @File2 TO "FILE2"


PERMIT

PERMIT is used under UNIX to set the permissions (mode) of a file, directory, or device. Permissions specify who can read, write, or execute a file, and who can search a directory. Only the owner of a file or the super-user can change the permissions of a file. To change file attributes under DOS, Windows, and NT, use the PROTECT statement. Example:

PERMIT "file";OWNER : READ,WRITE;GROUP : READ;OTHER : READ


PRINT LABEL and READ LABEL

PRINT LABEL and READ LABEL are used to set and read the volume label of a disk drive. Under UNIX, labels are not supported. Under DOS, Windows, and NT, HTBasic does not support PRINT LABEL; you must use the DOS/NT "LABEL" command. This example shows the use of READ LABEL under DOS:

10    MASS STORAGE IS "C:"
20    READ LABEL A$
30    IF A$="No Label" THEN
40      PRINT "The volume in drive C has no label"
50    ELSE
60      PRINT "The volume in drive C is ";A$
70    END IF
80    END


PROTECT

PROTECT is used to set LIF file passwords under HP BASIC and DOS/NT file attributes under HTBasic. It is not used by UNIX versions. To change file permissions under UNIX, use the PERMIT statement.

A special form of PROTECT is used by DOS and Windows versions of HTBasic to change file attributes. The syntax is

PROTECT file-specifier, protect-code

where protect-code is a string containing zero or more of the following characters:

Character	Meaning
(none)	no protection
R	read-only: File cannot be written or deleted.
S	system file: For the most part, this attribute
has no meaning.
H	hidden: File will not be listed by CAT.

If a character is not included, that attribute is cleared. If the string is blank, all attributes are cleared. For example:

PROTECT "FILE1","R"


PURGE

PURGE is used to delete files and directories. Under UNIX, the directory entry is deleted and the link count is decremented. When the link count reaches zero, the file is actually deleted.

PURGE "FILE1"


RENAME

RENAME is used to change the name of a file, but can also be used under DOS, Windows, and UNIX to move a file from one directory to another directory on the same disk. Under NT, it can even move a file to another disk.

RENAME "C:\HTB\AUTOST" TO "C:\AUTOST.BAS"


RESET

When RESET is used with a file, the file position is set to the beginning of the file.

10    ASSIGN @I TO "TEMP.TXT";FORMAT ON
20    OUTPUT @I;"HELLO"
30    RESET @I
40    ENTER @I;A$
50    PRINT A$
60    END


SYSTEM$("MSI")

SYSTEM$("MSI") allows you to read the present MASS STORAGE IS path specifier.

PRINT "The present MSI is ";SYSTEM$("MSI")


WILDCARDS

The WILDCARDS statement enables or disables wildcard support. Wildcards are characters that can be used in a filename as a template to select a group of files to be operated upon. A filename with wildcard characters in it will be compared with existing filenames using special rules and all filenames that "match" are acted upon. Under HTBasic, wildcards are supported only in the CAT statement.

Under DOS, Windows, and NT, if the WILDCARDS statement is executed, it will return an error because wildcarding is always on. The question mark "?" and the asterisk "*" are the DOS/NT wildcard characters.

Under UNIX, wildcarding is ON by default and the ESCAPE character is the backslash, "\". The ESCAPE character can be set to a backslash, a forward apostrophe, or an empty string (no ESCAPE character). For example,

WILDCARDS UX;ESCAPE "\"

The wildcard rules for HTBasic are similar to the rules used by the UNIX shells. The following table gives the wildcarding rules.

Wildcard	Rule
?	match one character
*	match zero or more characters
[set]	match one character from the set
[!set]	match one character not in the set
\	Escape meaning of next character


File Types

HTBasic supports several file types. Typed files for data are LIF ASCII and BDAT. HTBasic also supports files without a file type. HTBasic calls such files ordinary files. HP BASIC calls them HP-UX files. Most DOS, NT, and UNIX files are ordinary files. The format of data written to these files with FORMAT OFF is explained in Chapter 7.


BDAT Files

BDAT files, by default, are FORMAT OFF and are used to hold binary data. They may also be ASSIGNed with FORMAT ON and used to hold ASCII data. BDAT files may be accessed sequentially or randomly. The record size for random access is established when the file is CREATEd. If not specified, it defaults to 256 bytes.


ASCII Files

ASCII files are LIF ASCII files and are not compatible with DOS ASCII or UNIX ASCII files. See "Ordinary Files" below to learn how to create a DOS ASCII or UNIX ASCII file. A LIF ASCII file is compatible with HP BASIC ASCII files and is most useful when exchanging data using LIF floppies. In a CAT listing, a LIF ASCII file is listed as file type "ASCII". LIF ASCII files are always written with FORMAT ON and can only be accessed sequentially.


Ordinary Files

Ordinary files are files that do not have a file type. HP added ordinary files to HP BASIC 5.0 and called them "HP-UX" files. The name is somewhat misleading since the same file is called a "DOS" file when on a DOS computer.

By default, ordinary files are written with FORMAT OFF, but FORMAT ON may also be used. If you wish to create or access a DOS ASCII file, use an ordinary file with FORMAT ON. A DOS ASCII file contains characters that are all in the printable ASCII range, and lines are terminated with a carriage return, line feed (CR/LF) sequence. If you wish to create or access a UNIX ASCII file, use an ordinary file with FORMAT ON and EOL CHR$(10). Lines are terminated in a UNIX ASCII file with just a line feed.

10   CREATE "TEMP.TXT",512	! CREATE Ordinary file
20   ASSIGN @X TO "TEMP.TXT";FORMAT ON
 ! for DOS 30   INTEGER I
40   FOR I=1 TO 10
50     OUTPUT @X;"Line #";I
60   NEXT I
70   ASSIGN @X TO *
80   END


File Organization

"Random" and "sequential" are not file types, but are methods of organizing and accessing the information in a file. In fact, a BDAT or ordinary file can be accessed either way, even in the same program. A file should be organized, sequentially or randomly, based on how the file will be used.


Sequential Files

In sequential files, each data item is stored immediately following the previous one. The data in the file is stored in the order that it is produced. The data is read in the same order that it is stored. You read a sequential file from beginning to end. This results in a compact data storage structure and ease of programming.

The following example uses three files with sequential organization. The first two contain sorted data. They are merged to create the third file. Merging two files lends itself well to sequential organization.

10    REM MERGE.BAS -- Merge two sorted files
20    CREATE ASCII "merged",10
30    ASSIGN @F1 TO "file1";FORMAT ON
40    ASSIGN @F2 TO "file2";FORMAT ON
50    ASSIGN @M TO "merged";FORMAT ON
60    DIM Key1$[80],Key2$[80]
70    ON END @F1 GOTO Endf1
80    ON END @F2 GOTO Endf2
90    ENTER @F1;Key1$
100   ENTER @F2;Key2$
110   LOOP
120     IF Key1$>Key2$ THEN
130       OUTPUT @M;Key2$
140       ENTER @F2;Key2$
150     ELSE
160       OUTPUT @M;Key1$
170       ENTER @F1;Key1$
180     END IF
190   END LOOP
200 Endf1:! only file2 has any more data
210   ON END @F2 GOTO Alldone
220   LOOP
230     OUTPUT @M;Key2$
240     ENTER @F2;Key2$
250   END LOOP
260 Endf2:! only file1 has any more data
270   ON END @F1 GOTO Alldone
280   LOOP
290     OUTPUT @M;Key1$
300     ENTER @F1;Key1$
310   END LOOP
320 Alldone:! both files are out of data
330   ASSIGN @F1 TO *
340   ASSIGN @F2 TO *
350   ASSIGN @M TO *
360   END


Random Access Files

As mentioned previously, "random" is not a file type, but a method of organizing and accessing the information in a file. A file should be organized based on how the file will be used. Files in which the items are accessed in a random order should be organized as a random file.

BDAT files contain fixed length records that can be accessed by record number. The record number is specified after the I/O path variable. The record length is specified when creating the file. The record size must be set to accommodate the largest data item.

10    REM RANDOM.BAS -- Random file example (BDAT File)
20    DIM C$[56]
30    CREATE BDAT "customer.dat",100,60
40    ASSIGN @C TO "customer.dat"
50    CLEAR SCREEN
60    LOOP
70      DISP "A(dd, D(elete, S(how, Q(uit and take a vacation"
80      ON KBD GOTO Inkey
90      LOOP !endlessly until a key is pressed
100       OUTPUT CRT;TIME$(TIMEDATE);CHR$(13);
110     END LOOP
120 Inkey: K$=KBD$
130     OFF KBD
140     OUTPUT CRT
150     SELECT UPC$(K$)
160     CASE "A"
170       PRINT "Add:"
180       INPUT "Customer Number? ",C
190       INPUT "Information? ",C$
200       OUTPUT @C,C;C$
210       PRINT "Customer number #";C;"added"
220     CASE "D"
230       PRINT "Delete:"
240       INPUT "Customer Number? ",C
250       OUTPUT @C,C;"DELETED"
260       PRINT "Customer number #";C;"deleted"
270     CASE "S"
280       PRINT "Show:"
290       INPUT "Customer Number? ",C
300       ENTER @C,C;C$
310       PRINT "Customer number #";C;":",C$
320     CASE "Q"
330       PRINT "Thank you for using HTBasic!"
340       PRINT "Have a nice vacation."
350       DISP ! clear display line
360       STOP
370     CASE ELSE
380       PRINT CHR$(7);! ring the bell for a bad command
390     END SELECT
400   END LOOP
410   END

This example, of course, is not a complete application. But it does show the important aspects of random file use, as well as some user interface techniques. Note that the record size was declared to be 60. The length of each record can never exceed this, since each record consists of C$ (which can never be longer than 56 characters) plus the four byte length of C$ which we know will be included in the file since we are using a BDAT file with FORMAT OFF (the default).

Ordinary files do not have a physical record length, but you can still use a logical record length. The record number actually specifies the exact byte position in the file. The first byte is at position 1. To access a logical record, the byte position must be calculated based on the logical record length. The following example has the same capabilities as the previous program, but uses an ordinary file.

10    REM RANDOM.BAS -- Random file example (Ordinary File)
20    DIM C$[58]
30    Length=60                 ! 58 Character string + CR/LF
40    CREATE "customer.dat",100
50    ASSIGN @C TO "customer.dat";FORMAT ON
60    CLEAR SCREEN
70    LOOP
80      DISP "A(dd, D(elete, S(how, Q(uit and take a vacation"
90      ON KBD GOTO Inkey
100     LOOP              !endlessly until a key is pressed
110       OUTPUT CRT;TIME$(TIMEDATE);CHR$(13);
120     END LOOP
130 Inkey: K$=KBD$
140     OFF KBD
150     OUTPUT CRT
160     SELECT UPC$(K$)
170     CASE "A"
180       PRINT "Add:"
190       INPUT "Customer Number? ",C
200       INPUT "Information? ",C$
210       OUTPUT @C,(C-1)*Length+1;C$
220       PRINT "Customer number #";C;"added"
230     CASE "D"
240       PRINT "Delete:"
250       INPUT "Customer Number? ",C
260       OUTPUT @C,(C-1)*Length+1;"DELETED"
270       PRINT "Customer number #";C;"deleted"
280     CASE "S"
290       PRINT "Show:"
300       INPUT "Customer Number? ",C
310       ENTER @C,(C-1)*Length+1;C$
320       PRINT "Customer number #";C;":",C$
330     CASE "Q"
340       PRINT "Thank you for using HTBasic!"
350       PRINT "Have a nice vacation."
360       DISP ! clear display line
370       STOP
380     CASE ELSE
390       PRINT CHR$(7);! ring the bell for a bad command
400     END SELECT
410   END LOOP
420   END

BDAT files give an error if a single OUTPUT is too long for the record length (unless the record length is one). However, ordinary files do not give an error. It is the programmer's job to make sure that record overflow does not occur.


Converting LIF ASCII files to DOS ASCII

Sometimes it is advantageous to translate from a LIF ASCII file type to an ordinary DOS or UNIX file so that other DOS/UNIX programs can make use of the data.

The following program is an example showing the general principles of converting from one data type to another. It works for LIF ASCII to ordinary ASCII conversions, but may need to be modified to work in other situations.

10    REM ASCIIDOS.BAS
20    DIM Fi$[30],Fo$[30],L$[256]
30    INPUT "Input file?",Fi$
40    INPUT "Output file?",Fo$
50    ASSIGN @I TO Fi$;FORMAT ON
60    CREATE Fo$,1
70    ASSIGN @O TO Fo$;FORMAT ON
80    ON END @I GOTO Done
90    LOOP
100     ENTER @I;L$
110     OUTPUT @O;L$
120   END LOOP
130 Done: END

Knowing several general principles will help you write conversion programs to work in whatever situation you require. Line 50:  Open the input file using FORMAT ON, OFF, MSB FIRST, or whatever is appropriate. Line 60:  Create an output file of the type you wish to create. Line 70:  Open the output file using FORMAT ON, OFF, MSB FIRST, or whatever is appropriate. Line 100:  Enter the data with a statement compatible with how the data was written. For example, if integers were written in binary, then enter into integers with the file opened for binary access. Line 110:  Output the data in the format you wish it to be in. For example, if you wish three integers separated by commas, make sure you know how to use the OUTPUT statement to do so. Finally, use loop constructs (FOR, LOOP, REPEAT, or WHILE) to handle groups of data that are formatted the same.


IEEE-488 Interface Bus
Chapter 10
IEEE-488 Interface Bus

This chapter discusses the IEEE-488 (GPIB or HP-IB) bus and the HTBasic statements used to transfer information between devices. The history of the bus is presented along with an overview of its signal lines and device addressing. The different levels of IEEE-488 bus data transfer and control statements are also presented along with the HTBasic statements that enable and control IEEE-488 interrupts. A list of CONTROL, STATUS, READIO, and WRITEIO registers for the IEEE-488 is given. A summary of the bus actions that each IEEE-488 statement generates is also included.

This chapter does not explain installation of the IEEE-488 board or device driver. The Installing and Using manual contains the necessary installation and configuration information for device drivers included with HTBasic. For device drivers sold separately, the documentation included with the driver explains how to load and configure the driver.

This chapter assumes that you already have some familiarity with the operation of IEEE-488 bus and does not include a detailed bus operation description. Please consult any one of the many available books about the IEEE-488 bus for more detailed information about its operation.


IEEE-488 History

The IEEE-488 bus was developed to connect and control programmable instruments and to provide a standard interface for communication between instruments from different sources. Hewlett-Packard originally developed the interfacing technique and called it HP-IB. The interface quickly gained popularity in the computer industry. Because the interface was so versatile, the IEEE committee renamed it GPIB (General Purpose Interface Bus). All references to this interface bus in this chapter will use the name IEEE-488.


IEEE-488 Overview

Almost any instrument can be used with the IEEE-488 specification, because it says nothing about the function of the instrument itself, or about the form of the instrument's data. Instead the specification defines a separate component, the interface, that can be added to the instrument. The signals passing into the interface from the IEEE-488 bus and from the instrument are defined in the standard. The instrument does not have complete control over the interface. Often the bus controller tells the interface what to do. The active controller performs the bus control functions for all the bus instruments.

At power-up time, the IEEE-488 card that is programmed to be the  system controller becomes the active controller in charge. The system controller has several unique capabilities including the ability to send Interface Clear (IFC) and Remote Enable (REN) commands. IFC clears all device interfaces and returns control to the system controller. REN allows devices to respond to bus data once they are addressed to listen. The system controller may optionally Pass Control to another controller, which then becomes active controller.

There are 3 types of devices that can be connected to the IEEE-488  (listeners, Talkers, and controllers). Some devices include more than one of these functions. The standard allows a maximum of 15 devices to be connected on the same bus. A minimum system consists of one controller and one talker or listener device (i.e., a PC with a TransEra GPIB-900 board and a voltmeter).

It is possible to have several controllers on the bus but only one may be active at any given time. The active controller may pass control to another controller which in turn can pass it back or on to another controller. A listener is a device that can receive data from the bus when instructed by the controller and a talker transmits data on to the bus when instructed. The controller can set up a talker and a group of listeners so that it is possible to send data between groups of devices as well.

The IEEE-488 interface system consists of 16 signal lines and 8 ground lines. The 16 signal lines are divided into 3 groups (8 data lines, 3 handshake lines, and 5 interface management lines).


Data Lines

The lines DIO1 through DIO8 are used to transfer addresses, control information and data. The formats for addresses and control bytes are defined by the IEEE-488 standard. Data formats are undefined and may be ASCII (with or without parity) or binary. DIO1 is the Least Significant Bit (note that this will correspond to bit 0 on most computers).


Handshake Lines

The three handshake lines (NRFD, NDAC, DAV) control the transfer of message bytes among the devices and form the method for acknowledging the transfer of data. This handshaking process guarantees that the bytes on the data lines are sent and received without any transmission errors and is one of the unique features of the IEEE-488 bus.

The NRFD (Not Ready for Data) handshake line is asserted by a listener to indicate it is not yet ready for the next data or control byte. Note that the controller will not see NRFD released (i.e., ready for data) until all devices have released it.

The NDAC (Not Data Accepted) handshake line is asserted by a listener to indicate it has not yet accepted the data or control byte on the data lines. Note that the controller will not see NDAC released (i.e., data accepted) until all devices have released it.

The DAV (Data Valid) handshake line is asserted by the talker to indicate that a data or control byte has been placed on the data lines and has had the minimum specified stabilizing time. The byte can now be safely accepted by the devices.

 The handshaking process is outlined as follows. When the controller or a talker wishes to transmit data on the bus, it sets the DAV line high (data not valid) and checks to see that the NRFD and NDAC lines are both low, then it puts the data on the data lines.

When all the devices that can receive the data are ready, each releases its NRFD (not ready for data) line. When the last receiver releases NRFD and it goes high, the controller or talker takes DAV low indicating that valid data is now on the bus.

In response each receiver takes NRFD low again to indicate it is busy and releases NDAC (not data accepted) when it has received the data. When the last receiver has accepted the data, NDAC will go high and the controller or talker can set DAV high again to transmit the next byte of data.

Note that if after setting the DAV line high, the controller or talker senses that both NRFD and NDAC are high, an error will occur. Also, if any device fails to perform its part of the handshake and releases either NDAC or NRFD, data cannot be transmitted over the bus. Eventually a  timeout error will be generated.

The speed of the data transfer is controlled by the response of the slowest device on the bus; for this reason it is difficult to estimate data transfer rates on the IEEE-488 bus as they are device dependent.


Interface Management Lines

The five interface management lines (ATN, EOI, IFC, REN, SRQ) manage the flow of control and data bytes across the interface.

The ATN (Attention) signal is asserted by the controller to indicate that it is placing an address or control byte on the data bus. ATN is released to allow the assigned talker to place status or data on the data bus. The controller regains control by reasserting ATN; this is normally done synchronously with the handshake to avoid confusion between control and data bytes.

The EOI (End or Identify) signal has two uses. A talker may assert EOI simultaneously with the last byte of data to indicate end-of-data. The controller may assert EOI along with ATN to initiate a parallel poll. Although many devices do not use parallel poll, all devices should use EOI to end transfers (many currently available devices do not).

The IFC (Interface Clear) signal is asserted only by the system controller in order to initialize all device interfaces to a known state. After releasing IFC, the system controller becomes the active controller.

The REN (Remote Enable) signal is asserted only by the system controller. Its assertion does not place devices into remote control mode; REN only enables a device to go into remote mode when addressed to listen. When in remote mode, a device should ignore its local front panel controls.

The SRQ (Service Request) line is like an interrupt: it may be asserted by any device to request the controller to take some action. The controller must determine which device is asserting SRQ by conducting a serial poll. The requesting device releases SRQ when it is polled.


Device Addresses

The IEEE-488 standard allows up to 15 devices to be interconnected on one bus. Each device is assigned a unique primary address, ranging from 0-30, by setting the address switches on the device. A secondary address may also be specified, ranging from 0-30. See the device documentation for more information on how to set the device primary and optional secondary address.

In the HTBasic statements that access the bus, a device selector is used to specify the interface select code, the primary device address, and the optional secondary device address. The default IEEE-488 interface select code is 7. The default primary address of the system controller is 21. The following examples demonstrate how the interface and device addresses are specified.

Device Selectors	ISC code	Pri. Add	Sec. Add
705	7	5	none
72501	7	25	1
1207	12	7	none
100412	10	4	12

The primary address of the IEEE-488 board can be read using the STATUS statement and changed with the  CONTROL statement. Bits 0-4 of register three specify the primary address.

STATUS 7,3; Pri_add     !Read Primary Address
CONTROL 7,3; Pri_add    !Set Primary Address

A discussion of the CONTROL and STATUS statements is given later in this chapter.


IEEE-488 Statement Overview

HTBasic provides five levels of IEEE-488 statements: high level transfer, high level bus control, byte level transfer, low level bus control, and interface interrupt control.

The high level OUTPUT and ENTER statements allow you to easily send and receive data on the bus. All the necessary bus addressing commands are automatically generated.

The high level bus control statements allow you to abort transfers, reset the bus interface, clear specific bus devices, lockout local control of devices, return devices to their local state, pass active control to another, configure the parallel poll response, request service, perform a group execute trigger, and conduct parallel and serial polls.

The byte level SEND statement allows more detailed control over the bus. Because the user must generate all the proper bus addressing commands himself, use of this statement requires a more detailed knowledge about IEEE-488 bus operations.

The low level bus control statements CONTROL, STATUS, READIO, and WRITEIO allow you to directly access the IEEE-488 driver status and control registers and the controller hardware registers.

The interrupt control statements enable, control, and disable interrupts generated by the IEEE-488 interface hardware.


High Level Transfer Statements

The ENTER and OUTPUT statements are used to transfer data between IEEE-488 devices. They automatically generate all the required bus addressing. For a description of the ENTER and OUTPUT statements, see Chapter 7, "General Input and Output."  It explains how to send or suppress CR/LF line terminators and how to set the EOI signal line on the output of the last data byte. The following example demonstrates communication with an HP-GL plotter at device address five.

OUTPUT 705;"OP;"
ENTER 705;P1x,P1y,P2x,P2y

The OUTPUT statement requests the plotter to send its P points. The ENTER statement reads the P point values sent back by the plotter.

The powerful USING option gives you a high degree of control over the data format used for the transfer operations. For example:

OUTPUT 705 USING "#,K";Str$
ENTER 705 USING "#,K";Str$

Multiple listeners may also be addressed with the same command. As follows:

ASSIGN @Dev to 705,706,707,708
OUTPUT @Dev; "Data"

The OUTPUT statement listen-addresses the devices with primary addresses 5, 6, 7, and 8 and then sends the string "Data" to all of them. If the same I/O Path is used for the ENTER statement, the first device is addressed as the talker and the remaining devices, including the active controller, are addressed as listeners.

Some devices allow the selection of a particular mode of operation by the use of the secondary address. Multiple secondary addresses may be specified. This extended addressing mode is shown below.

ASSIGN @Dev to 7011011    !Secondary Address 10 and 11
OUTPUT @Dev; Str$
OUTPUT 70501; Str$        !Secondary Address 01

When the device is not the active controller, it cannot do any bus addressing. If only the interface select code is used for the ENTER and OUTPUT statements, no bus addressing will be performed. The device must make sure that it has been addressed to talk or listen before it participates in the transfer of data. If it has not been addressed, then the device will wait until it is addressed before continuing.

OUTPUT 7; Str$
ENTER 7; Str$


High Level Bus Control Statements

HTBasic provides many high level IEEE-488 bus control statements. The actions taken on the IEEE-488 bus by each control statement are determined by three things:

1) whether the device issuing the command is the system controller,
2) whether the device is the active controller, and
3) whether the command was issued with only the interface select code or a primary address was specified.

Each statement is discussed in the following paragraphs. Also, a quick bus actions reference is provided at the end of this chapter.


ABORT Statement

The ABORT statement stops IEEE-488 bus activity. You specify either an interface select code or an I/O Path. This statement is only supported by the IEEE-488 interface. For example:

ABORT 7

If the computer is the system controller but not the active controller, ABORT causes the computer to assume active control.

If a primary address is specified, an error is generated. If the computer is the system controller, the bus action is to issue IFC for greater than 100 micro-seconds and then to assert REN and de-assert ATN. If the computer is not the system controller but is the active controller, the bus action is: ATN, MTA, UNL, and de-assert ATN. If it is not the active controller either, no action is taken.


CLEAR Statement

The CLEAR statement causes the active controller to send a Device Clear command to one or more devices. The effect on the device is device-dependent. You specify either an device selector or an I/O Path. This statement is only supported by the IEEE-488 interface. For example:

ASSIGN @Counter to 7
CLEAR @Counter

If primary addressing is specified, the bus action is: ATN, MTA, UNL, LAG, SDC. If only an interface select code is specified, the bus action is: ATN,  DCL. If the computer is not the active controller, an error is generated.


LOCAL Statement

The LOCAL statement returns specified IEEE-488 devices to their local (front panel) state. You specify either a device selector or an I/O Path. This statement is only supported by the IEEE-488 interface. For example:

LOCAL 728

If a primary device address is specified, a Go To Local (GTL) message is sent to all listeners and LOCAL LOCKOUT is not canceled. If only an interface select code is specified, all devices on the bus are returned to the local state and LOCAL LOCKOUT is canceled.

If a primary device address is specified and the computer is the active controller, the bus activity is: ATN, MTA, UNL, LAG, GTL.

If the computer is not the active controller but is the system controller and just an interface select code is specified, the REN line is set false. If it is also the active controller, the ATN and REN lines are both set false.

When the computer is not the system controller but is the active controller, the bus activity for an Interface Select Code is to set the ATN line and send a GTL message. When it is not the active controller, an error is generated.


LOCAL LOCKOUT Statement

The LOCAL LOCKOUT statement sends the LLO message over the IEEE-488 bus. This prevents front panel control of IEEE-488 devices that are in the remote state. You specify either an interface select code or an I/O Path. This statement is only supported by the IEEE-488 interface. For example:

LOCAL LOCKOUT 7

If the computer is not the active controller or a primary device address is specified, an error is generated. If only an interface select code is specified, the bus action is ATN, LLO. If an I/O Path is specified, it must refer to the IEEE-488 interface.


PASS CONTROL Statement

The PASS CONTROL statement passes active controller capability to the specified IEEE-488 device. You specify either a device selector or an I/O Path. If an I/O Path is specified, it must be assigned to an IEEE-488 device. For example:

ASSIGN @Dev to 705
PASS CONTROL @Dev

If the computer is the active controller and a primary address is specified, control is passed to the addressed device. An error is generated if the computer is not the active controller or if only an interface select code is specified.

The specified device is talk addressed, a Take-Control-Message TCT is sent, and the Attention line is set false. The computer then becomes a bus device, as opposed to a bus controller.


PPOLL Function

The PPOLL function conducts a Parallel Poll of the IEEE-488 and the 8-bit status message from the IEEE-488 bus is returned. Each bit corresponds to the status of a device which is configured to respond to a parallel poll. You specify either an interface select code or an I/O Path as the function argument. This statement is only supported by the IEEE-488 interface. For example:

ASSIGN @Gpib to 7
Pstatus = PPOLL(@Gpib)

If an interface select code is specified, the bus action is as follows: ATN and EOI are set for ≥25 microsec., one byte of data is read from the bus, EOI is released, and ATN is restored to its previous state. If the computer is not the active controller or a primary device address is specified, an error is generated.


PPOLL CONFIGURE Statement

The PPOLL CONFIGURE statement configures the parallel poll response for the specified remote IEEE-488 device(s). You specify either an I/O Path or a device selector that refers to one or more IEEE-488 devices and a parallel poll configuration value from zero through 15. The three least significant bits of its binary representation select the data bus line and the fourth bit selects the logical sense of the response. For example:

PPOLL CONFIGURE 702;3

configures device number two on interface number seven to respond on data line DIO4 with a logic sense of zero when its status bit is set.

If the computer is not the active controller or if only an interface select code is specified, an error is generated. The bus action is as follows: ATN, MTA, UNL, LAG, PPC, PPE.


PPOLL RESPONSE Statement

The PPOLL RESPONSE statement enables or disables the local IEEE-488 device parallel poll response to an active controller parallel poll request. You specify either an interface select code or an I/O Path and an enable value. An enable value of one enables the parallel poll response, whereas a zero value disables it. This statement is only supported by the IEEE-488 interface. For example:

ASSIGN @Gpib to 7
PPOLL RESPONSE @Gpib;1

The device must have been previously configured for a parallel poll response with the PARALLEL CONFIGURE statement.


PPOLL UNCONFIGURE Statement

The PPOLL UNCONFIGURE statement disables the parallel poll response of the specified IEEE-488 device or devices. You specify either an I/O Path or a device selector that refers to one or more IEEE-488 devices. If only an interface select code is specified, all devices are deactivated from the parallel poll response. For example:

ASSIGN @Dev to 7
PPOLL UNCONFIGURE @Dev

If the computer is not the active controller, an error is generated. If a primary device address is specified, the bus action is: ATN, MTA, UNL, LAG, PPC, PPD; otherwise the bus action is: ATN, PPU.


REMOTE Statement

The REMOTE statement sets the remote state on an IEEE-488 device by asserting the IEEE-488 bus remote line (REN). The device will switch to a remote state only after it has been addressed to listen, causing the front panel to be disabled. You specify either an I/O Path or a device selector that refers to one or more IEEE-488 devices. For example:

REMOTE 702

If the computer is the active controller and primary addresses are specified, the computer listen addresses the devices to switch them to remote mode. The bus action is:  REN, ATN, MTA, UNL, LAG. The remote line is asserted if the computer is the system controller and ISC select code is specified. If the computer is not the system controller or it is not the active controller, an error is generated.


REQUEST Statement

The REQUEST statement sends a Service Request (SRQ) on the IEEE-488 bus. You specify either an interface select code or an I/O Path and a service value. To request service, the response value must have bit six set. The SRQ line will remain set until polled by the active controller or another REQUEST statement is executed with bit six clear. For example:

REQUEST 7;Bit3+Bit4+Bit6

If the computer is the active controller or if the device-selector or the I/O Path specifies address information, an error is generated.


RESET Statement

The RESET statement resets the IEEE-488 interface. It asserts the IFC line for more than 100 ms, clears interrupts, and if the interface is the system controller, sets it to be the active controller. For example:

RESET 7


SPOLL Function

The SPOLL function performs a serial poll of an IEEE-488 device and returns the serial poll response, specifying whether the device is requesting service. You specify either an I/O Path or a device selector. The computer must be the active controller and a primary device address must be specified, otherwise an error is generated. One secondary address may also be specified. For example:

Stat = SPOLL(712)

The IEEE-488 bus action is: ATN, UNL, MLA, TAG, SPE not-ATN, Read data byte, ATN, SPD, UNT.


TRIGGER Statement

The TRIGGER statement allows the active controller to send a trigger message to a specified IEEE-488 device or to all listen addressed devices on the IEEE-488 bus. You specify either an I/O Path or a device selector that refers to one or more IEEE-488 devices. For example:

ASSIGN @Gpib to 705
TRIGGER @Gpib

If primary device addresses are specified, the bus action is: ATN, UNL, LAG, GET. If only an interface select code is specified, the bus action is: ATN, GET. If the computer is not the active controller, an error is generated.


Byte Level Transfer Statements

If you need more control over the bytes transferred over the bus than the high level OUTPUT and ENTER statements allow, you can use the SEND statement as described in the following paragraphs. The OUTPUT and ENTER statements may also be used for byte level transfers under certain circumstances.

Before you can communicate with a device on the IEEE-488 bus, the talker device and the listener device(s) need to be addressed. The high level OUTPUT and ENTER transfer statements generate the necessary device addressing for you. When using the SEND statement, you must generate all the proper bus addressing commands yourself. This requires a more detailed knowledge about IEEE-488 bus operations than is presented here. Please consult any one of the many available books about the IEEE-488 bus or your IEEE-488 bus device manuals.


SEND Statement

The SEND statement sends byte level IEEE-488 bus data and commands. Commands are sent with the ATN line asserted; whereas data bytes are sent without the ATN line asserted. You specify an I/O Path or an interface select code and a list of messages. The type of message is specified with the keywords CMD, DATA, TALK, LISTEN, SEC, MTA, MLA, UNT, and UNL. For example:

SEND @Gpib; UNL MLA TALK Primary CMD 24+128

sends the unlisten command, my listen address, the talk address specified by the value of the variable (Primary), and then the command byte 152.

The CMD message evaluates the following expression values and sends them as command bytes. If the CMD keyword is given with no expressions, it asserts the ATN line. For example:

SEND 7; CMD 3*5, P, A$, N

The DATA message evaluates the following expression values and sends them as data bytes. If the optional END keyword is added, EOI is set on the last data byte. For example:

SEND 7; DATA Value*4, ABS(N), Out$ END

The LISTEN message sends the expression values as listen address commands. The TALK message sends the expression value as a talk address command. The SEC message sends the expression values as secondary address commands. The MLA message sends the interface's listen address command. The MTA message sends the interface's talk address command. The UNL message sends the unlisten command and the UNT message sends the untalk command.

The computer must be the active controller to use the CMD, TALK, UNT, LISTEN, UNL, SEC, MTA, or MLA messages. Any talk addressed device may send DATA.

The following table lists the bus commands that can be sent with the CMD message.

Decimal Value	Description
1	GTL - Go to Local
4	SDC - Selected Device Clear
5	PPC - Parallel Poll Configure
8	GET - Group Execute Trigger
9	TCT - Take Control
17	LLO - Local Lockout
20	DCL - Device Clear
21	PPU - Parallel Poll Unconfigure
24	SPE - Serial Poll Enable
25	SPD - Serial Poll Disable
32-62	LAG - Listen Address Group
63	UNL - Unlisten
64-94	TAG - Talk Address Group
95	UNT - Untalk
96-111	PPE - Parallel Poll Enable
112-126	PPD - Parallel Poll Disable
96-126	SCG - Secondary Command Group

Note that the listen and talk address groups (LAG and TAG) consist of 31 different addresses. Each listen and talk address can be further broken down into a secondary address group (SCG). To find the appropriate listen, talk, or secondary address to send for a particular device, use the following equations:

Listen Address = Primary Address + 32
Talk Address = Primary Address + 64
Secondary Address = Primary Address + 96

The examples below show the high level transfer statement OUTPUT followed by four ways to send the exact same information across the IEEE-488 bus with the SEND statement.

OUTPUT 705 USING "#,K";"gt;"

SEND 7; CMD "?U%" DATA "gt;" END
SEND 7; CMD 32+31, 64+21, 32+5 DATA "gt;" END
SEND 7; UNL MTA LISTEN 5 DATA "gt;" END
SEND 7; UNL TALK 21 LISTEN 5 DATA "gt;" END


OUTPUT and ENTER Statements

The OUTPUT and ENTER statements can also be used for byte level transfers. If only the interface select code is specified in the OUTPUT and ENTER statements, no bus addressing is performed.

If the device is the active controller then no addressing needs to be done, as long as the addressing has been done once. The talker and listener still need to remain addressed for transfers to take place. For example:

10  ENTER 705; Str$
20  FOR I=1 to 10
30    ENTER 7; Str$
40    PRINT Str$
50  NEXT I
60  END

This type of addressing will reduce the bus addressing overhead for each piece of data read. However, we do not recommend this practice because branching to an interrupt service routine may destroy the current talker or listener setup.

When the device is not the active controller, it cannot do any bus addressing. The device must make sure that it has been addressed to talk or listen before it participates in the transfer of data. If it has not been addressed, then the device will wait until it is addressed before continuing. For example:

OUTPUT 7; Str$  !Waits Until Talker Addressed
ENTER 7; Str$   !Waits Until Listener Addressed

A combination of the SEND and the ENTER statements can emulate any of the high level transfer or bus control statements. As an example, let's see how to conduct a serial poll (SPOLL) operation using these statements.

Poll_value = SPOLL(705)         !High level command

SEND 7; CMD "?5E" CMD 24        !Output SPE command
ENTER 7 USING "#,B";Poll_value  !Read Poll Value
SEND 7; CMD 25 UNT              !Output SPD command

You are limited in your control of the IEEE-488 bus only by your imagination and skill at combining the SEND and ENTER statements.


Low Level Bus Control Statements

The low level bus control statements allow you to access the status and control registers in both the IEEE-488 driver and in the IEEE-488 controller hardware. The CONTROL and STATUS statements access the IEEE-488 driver registers while the READIO and WRITEIO statements access the controller hardware registers. The definitions of these registers are given near the end of this chapter.


CONTROL and STATUS Statements

The CONTROL and STATUS statements allow you to configure the serial and parallel poll response bytes, change the primary address, set interrupt mask registers, read the status of the data and bus lines, read the interrupt status, and read the controller status and address. The following program reads the STATUS registers and prints the values out in both decimal and binary.

10  STATUS 7;X0,X1,X2,X3,X4,X5,X6,X7 !Read all Status Registers
20  PRINT X0,X1,X2,X3,X4,X5,X6,X67
30  PRINT IVAL$(X0,2),IVAL$(X1,2),IVAL$(X2,2),IVAL$(X3,2)
40  PRINT IVAL$(X4,2),IVAL$(X5,2),IVAL$(X6,2),IVAL(X7,2)
50  END


READIO and WRITEIO Statements

The READIO and WRITEIO statements directly access the IEEE-488 controller hardware registers. Do not attempt to use the READIO and WRITEIO registers unless you are very familiar with the hardware. Use the STATUS and CONTROL registers instead.

Accessing hardware registers can cause your system to crash, data to be lost, or damage to your computer hardware. TransEra cannot be held responsible for any consequences. If you need technical assistance from TransEra, it will be provided at the current consulting rates.


IEEE-488 Interrupts

Interrupts allow the computer to perform other tasks while you wait for some condition to occur. This eliminates the need to continually monitor the STATUS register for some event. HTBasic has the capability of monitoring up to 16 different interrupt conditions at once.


ON INTR Statement

The ON INTR statement defines an event branch to be taken when an interface card generates an interrupt. You specify the interface select code, an optional priority and the branch type. The branch type may be either a GOTO, GOSUB, CALL, or RECOVER. For example:

ON INTR 7,4 GOSUB Repair

When an interrupt occurs a DISABLE INTR for the interface is automatically executed. Consequently, an ENABLE INTR statement must be used to explicitly re-enable interrupts.

The default priority is one. The highest priority that can be specified is 15. ON END, ON ERROR, and ON TIMEOUT have a higher priority than ON INTR. When an INTR initiated branch is taken with a GOTO, the system priority is not changed. When an ON INTR branch specifies a CALL or GOSUB, the system priority is changed to the specified priority.

RECOVER causes the program to SUBEXIT from contexts as needed to return to the defining context and resume execution at the specified program line. ON INTR statements that specify CALL or RECOVER will be serviced even if the program context has been changed to another subprogram. ON INTR statements that specify GOTO or GOSUB will be logged and then serviced when control returns to the defining program context.

ON INTR is canceled by OFF INTR, disabled by DISABLE or DISABLE INTR. The following example shows how to detect the IEEE-488 service request (SRQ).

10   ON INTR 7 GOSUB 80 !Where to Go When Interrupt Occurs
20   ENABLE INTR 7;2    !Enable SRQ Interrupt
30     . . .
40     . . .
50     . . .
60   STOP
70   !
80   Val = SPOLL(701)   !Clear SRQ Line
90   ENTER 701;Condition!Read Device Condition
100  PRINT Condition
110  ENABLE INTR 7      !Re-Enable SRQ Interrupt
120  RETURN
130  END


OFF INTR Statement

The OFF INTR statement cancels event branches defined by ON INTR. Any INTR events that have been logged but not yet serviced are canceled. An OFF INTR statement without the optional interface select code disables event-initiated branches on all devices. If the interface select code is specified, only that interface interrupt will be disabled. For example,

OFF INTR 7

cancels event branches for the IEEE-488 interface.


Enabling and Disabling Interrupts

The DISABLE statement disables all defined event branches except END, ERROR, and TIMEOUT. While disabled, the first event of each type that occurs is logged. When event branching is re-enabled with the ENABLE statement, all logged events are serviced in the order of their event priorities.

The DISABLE INTR statement disables interrupts from just the specified interface. For example,

DISABLE INTR 7

disables interrupts from the IEEE-488 interface.

The ENABLE INTR statement enables interrupts from a specified interface. An optional bit mask is stored in the interface interrupt-enable register. The default bit mask is the previous bit mask for that interface, or if there is no previous bit mask then a bit mask of all zeros is used. The meaning of the bit mask depends on the interface; consult the interface documentation. For example,

ENABLE INTR 7;Bitmask

enables interrupts on the IEEE-488 interface and stores the value of the variable Bitmask into the interface interrupt-enable register. The interrupt enable register bits are defined as follows:


Interrupt Enable Register Bit Mask.

Bit	Value	Meaning
15	-32768	Active Controller
14	16384	Parallel Poll Config. change
13	8192	My Talk address received
12	4096	My Listen address received
11	2048	EOI received
10	1024	SPAS
9	512	Remote/Local change
8	256	Talker/Listener Address change
7	128	Trigger received
6	64	Handshake Error
5	32	Unrecognized universal command
4	16	Secondary command while addressed
3	8	Clear received
2	4	Unrecognized addressed command
1	2	SRQ received
0	1	IFC received

The interrupt enable register has the same bit values as STATUS registers 4 and 5. STATUS register 4 tells which condition caused the interrupt. STATUS register 5 tells which interrupts are enabled. To enable more than one interrupt, add up all the event decimal values and use this value as the ENABLE INTR bit mask.


Handling Service Requests

HTBasic can be programmed to branch to a service routine when a device requests service. The example at the start of this chapter shows how to set up and enable an interrupt for the SRQ line. When a device sets the SRQ line, your service routine needs to perform the following steps: 1) find out which device is requesting service, 2) find out what action needs to be taken, 3) perform the needed action, 4) re-enable the IEEE-488 interrupts.

Step 1 uses either the PPOLL command or the SPOLL command. With the SPOLL command you have to start with the first address and step through all the addresses, until you find the device requesting service. If you only have one or two devices on the IEEE-488 bus, then this method is quite fast and it eliminates step two.

Step 2 uses a serial poll (SPOLL) to read the device response byte and tells the device that it is being serviced. The device then removes the request by clearing the SRQ line.

Step 3 is dependent on the response byte value. Its interpretation is determined by the device documentation.

Step 4 re-enables the interrupts with the ENABLE INTR command. Interrupts are disabled by the Controller until the current request has been serviced. Once serviced, the interrupts need to be re-enabled.


Parallel Polling Devices

A parallel poll is the fastest way of determining the requesting device. Each device must first be programmed to respond to a parallel poll request on a unique data line (DIO1 - DIO8). For example,

PPOLL CONFIGURE 705;11

configures device 5 to respond by placing a 1 on data line DIO4. Bit 3 determines the logic sense of the data line when the device needs service. The data line to use is determined by bits 0-2, offset by one. A value of 3 means use data line DIO4.

To disable a device from responding to a parallel poll use the following commands.

PPOLL UNCONFIGURE 705   !Disables Device 5
PPOLL UNCONFIGURE 7     !Disables All Devices

To conduct the parallel poll the PPOLL function is used as follows:

Pstatus = PPOLL(7)   !Parallel Poll Bus

After the parallel poll the variable Pstatus contains the value of the 8 data lines as set by the devices that have been configured to respond to the parallel poll.


IEEE-488 Registers

STATUS and CONTROL registers for IEEE-488 interfaces are given below. READIO and WRITEIO registers are presented for 9914 and 7210 based IEEE-488 interfaces.

IEEE-488 hardware is not supplied standard with most computers. For the DOS and Windows versions of HTBasic, TransEra sells the GPIB-900 IEEE-488 Controller. The board fits in any XT or AT bus slot. The board incorporates the TI TMS9914 integrated circuit, the same controller used in HP BASIC workstations. This board provides compatibility with HP BASIC at all levels, including the READIO/WRITEIO level which accesses the 9914 registers directly.

HTBasic also supports most PC IEEE-488 boards from other manufacturers. These boards most often use the NEC PD7210 Chip and consequently are not completely compatible with HP BASIC. STATUS and CONTROL registers for the 9914 and the 7210 are the same, although some bits can not be supported by the 7210. The READIO/WRITEIO registers of the 7210 are completely different from the 9914 used by HP BASIC. Different tables are given below for the 7210 and the 9914.

READIO/WRITEIO registers allow direct access to the interface hardware. You should not attempt to use these registers unless you are familiar with how the IEEE-488 chip is programmed. For documentation on the 9914 IEEE-488 chip, please refer to the Texas Instruments Data Manual, available from Texas Instruments. For documentation on the 7210 IEEE-488 chip, please refer to the NEC General Purpose Interface Bus Manual, available from NEC.

The ON INTR 7 and ENABLE INTR 7 statements are supported. The values for the enable mask in the ENABLE INTR statement are the same as those for STATUS register 5, given below. Some interrupts are not supported by the 7210.


IEEE-488 CONTROL Registers

The following CONTROL registers are supported.


CONTROL 0

Reset. The value must be non-zero.


CONTROL 1

Set Serial Poll Response Byte.

Bit	Value	Meaning
7	128	Device Dependent Status
6	64	SRQ 1 - It's me, 0 - It's not me.
5-0	-	Device Dependent Status


CONTROL 2

Set Parallel Poll Response Byte.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


CONTROL 3

Set My Bus Address.

Bit	Value	Meaning
7-5	-	Unused
4-0	-	Interface Primary Address


CONTROL 4

Release NDAC Holdoff. 0 - No Secondary Address, 1 - Accept Secondary.


CONTROL 5

Set Parallel Poll Response Mask.

Bit	Value	Meaning
7-5	-	Unused
4	16	Unconfigure
3	8	Logic Sense
2-0	-	Bits used for response


IEEE-488 STATUS Registers

The following STATUS registers are supported.


STATUS 0

Return Identification. Always 1.


STATUS 1

Return Interrupt and DMA status.

Bit	Value	Meaning
7	128	Interrupts Enabled
6	64	Interrupt Requested
5-4	-	Hardware Interrupt Level Switches
3-2	-	Not used
1	2	DMA channel 1 enabled
0	1	DMA channel 0 enabled


STATUS 2

Return Busy Bits.

Bit	Value	Meaning
7-3	-	Unused
2	4	Handshake in progress
1	2	Interrupts Enabled
0	1	TRANSFER in progress


STATUS 3

Return Controller Status and Address.

Bit	Value	Meaning
7	128	System Controller
6	64	Active Controller
5	32	Unused
4-0	-	Interface Primary Address


STATUS 4

Return Interrupt Status. Uses same bit definitions as register 5.


STATUS 5

Return Interrupt Enable Mask. Use these values with ENABLE INTR to enable interrupts.

Bit	Value	Meaning
15	-32768	Active Controller
14	16384	Parallel Poll Config. change
13	8192	My Talk address received
12	4096	My Listen address received
11	2048	EOI received
10	1024	SPAS
9	512	Remote/Local change
8	256	Talker/Listener Address change
7	128	Trigger received
6	64	Handshake Error
5	32	Unrecognized universal command
4	16	Secondary command while addressed
3	8	Clear received
2	4	Unrecognized addressed command
1	2	SRQ received
0	1	IFC received*

*Not supported by the NEC 7210.


STATUS 6

Return Interface Status. The REM & LOC bits are not always accurate on NEC 7210 cards.

Bit	Value	Meaning
15	-32768	REM
14	16384	LLO
13	8192	ATN True
12	4096	LPAS
11	2048	TPAS
10	1024	LADS
9	512	TADS
8	256	LSB of last address
7	128	System Controller
6	64	Active Controller
5	32	Unused
4-0	-	Primary Interface Address


STATUS 7

Return Bus Control and Data Lines.

Bit	Value	Meaning
15	-32768	ATN True
14	16384	DAV True*
13	8192	NDAC True*
12	4096	NRFD True*
11	2048	EOI True
10	1024	SRQ True
9	512	IFC True*
8	256	REN True
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1

* Not supported by the NEC 7210.


9914 READIO Registers

The following READIO registers are supported.


9914 READIO 1

Return Card Identification. Always 1.


9914 READIO 3

Return Interrupt and DMA status.

Bit	Value	Meaning
7	128	Interrupts Enabled
6	64	Interrupt Requested
5-4	-	Hardware Interrupt Level Switches
3-2	-	Not used
1	2	DMA channel 1 enabled
0	1	DMA channel 0 enabled


9914 READIO 5

Return Controller Status and Address.

Bit	Value	Meaning
7	128	System Controller
6	64	Not Active Controller
5	32	Unused
4-0	-	Interface Primary Address


9914 READIO 17

Return Interrupt Status Register 0.

Bit	Value	Meaning
7	128	Interrupt occurred on ISR 0
6	64	Interrupt occurred on ISR 1
5	32	Byte Received
4	16	Ready for Next Byte
3	8	EOI detected
2	4	SPAS
1	2	Remote/Local Change
0	1	My Address Change


9914 READIO 19

Return Interrupt Status Register 1.

Bit	Value	Meaning
7	128	Trigger Received
6	64	Handshake Error
5	32	Unrecognized Command Group
4	16	Secondary Command While Addressed
3	8	Clear Received
2	4	My Address Received (Listen or Talk)
1	2	SRQ Received
0	1	IFC Received


9914 READIO 21

Return Interface Status.

Bit	Value	Meaning
7	128	REM - Remote State
6	64	LLO - Local Lockout State
5	32	ATN Line True
4	16	LPAS - Listener Primary Addressed State
3	8	TPAS - Talker Primary Addressed State
2	4	LADS - Listener Addressed State
1	2	TADS - Talker Primary Addressed State
0	1	LSB of Last Address


9914 READIO 23

Return Control-Line Status.

Bit	Value	Meaning
7	128	ATN True
6	64	DAV True
5	32	NDAC True
4	16	NRFD True
3	8	EOI True
2	4	SRQ True
1	2	IFC True
0	1	REN True


9914 READIO 29

Return Command Pass Through.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


9914 READIO 31

Return Bus Data Line Status.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


9914 WRITEIO Registers

The following WRITEIO registers are supported.


9914 WRITEIO 3

Set Interrupt and DMA Enable.

Bit	Value	Meaning
7	128	Enable Interrupt
6-2	-	Unused
1	2	Enable DMA Channel 1
0	1	Enable DMA Channel 0


9914 WRITEIO 17

Set Interrupt Mask Register 0.

Bit	Value	Meaning
7-6	Unused
5	32	Byte Received
4	16	Ready for Next Byte
3	8	EOI detected
2	4	SPAS
1	2	Remote/Local Change
0	1	My Address Change


9914 WRITEIO 19

Set Interrupt Mask Register 1.

Bit	Value	Meaning
7	128	Trigger Received
6	64	Handshake Error
5	32	Unrecognized Command Group
4	16	Secondary Command While Addressed
3	8	Clear Received
2	4	My Address Received (Listen or Talk)
1	2	SRQ Received
0	1	IFC Received


9914 WRITEIO 23

Set Auxiliary Command Register.

Bit	Value	Meaning
7	128	1 - Set, 0 - Clear
6-5	-	Unused
4-0	-	Auxiliary Command

Auxiliary Command	CLEAR	SET
Software Reset	0	128
Release DAC Holdoff	1	129
Release RFD Holdoff	2	xx
Holdoff on all Data	3	131
Holdoff on EOI only	4	132
New Byte Available False	5	xx
Force Group Execute Trigger	6	134
Return to Local	7	135
Send EOI with Next Byte	8	xx
Listen Only	9	137
Talk Only	10	138
Goto Standby	11	xx
Take Control Asynchronously	12	xx
Take Control Synchronously	13	xx
Request Parallel Poll	14	142
Send Interface Clear	15	143
Send Remote Enable	16	144
Request Control	17	xx
Release Control	18	xx
Disable all Interrupts	19	147
Pass Through Next Secondary	20	xx
Short T1 Settling Time	21	149
Shadow Handshake	22	150
Very Short T1 Delay	23	151
Request Service Bit 2	24	152


9914 WRITEIO 25

Set Address Register.

Bit	Value	Meaning
7	128	Enable Dual Addressing
6	64	Disable Listener Function
5	32	Disable Talker Function
4-0	-	Primary Address


9914 WRITEIO 27

Set Serial Poll Response.

Bit	Value	Meaning
7	128	Device Dependent Status
6	64	1 - Send, 0 - Don't Send SRQ
5-0	-	Device Dependent Status


9914 WRITEIO 29

Set Parallel Poll Response.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


9914 WRITEIO 31

Set Bus Data Lines Register.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


7210 READIO Registers

The following READIO registers are supported.


7210 READIO 1

Return Card Identification. Always 2.


7210 READIO 3

Return Interrupt and DMA status.

Bit	Value	Meaning
7	128	Interrupts Enabled
6	64	Interrupt Requested
5-4	-	Hardware Interrupt Level Switches
3-2	-	Not used
1	2	DMA channel 1 enabled
0	1	DMA channel 0 enabled


7210 READIO 5

Return Controller Status and Address.

Bit	Value	Meaning
7	128	System Controller
6	64	Active Controller
5	32	Unused
4-0	-	Interface Primary Address


7210 READIO 18

Return Bus Data Lines.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


7210 READIO 20

Return Interrupt Status Register 1.

Bit	Value	Meaning
7	128	Command Pass Through
6	64	Address Pass Through
5	32	Device Execute Trigger
4	16	End Received
3	8	Device Clear
2	4	Handshake Error
1	2	Data Out - Send Byte
0	1	Data In - Read Byte


7210 READIO 22

Return Interrupt Status Register 2.

Bit	Value	Meaning
7	128	Interrupt Occurred on ISR 1 or 2
6	64	SRQ Received
5	32	Device in Lockout State
4	16	Device in Remote State
3	8	Command Output - Send Byte
2	4	Lockout Change
1	2	Remote Change
0	1	Address Status Change


7210 READIO 24

Return Serial Poll Status.

Bit	Value	Meaning
7-0	-	Echoes Contents of Serial Poll Mode Reg.


7210 READIO 26

Return Address Status.

Bit	Value	Meaning
7	128	Controller in Charge
6	64	ATN Line is High
5	32	Serial Poll Mode State
4	16	Listener Primary Addressed State
3	8	Talker Primary Addressed State
2	4	Listener Addressed
1	2	Talker Addressed
0	1	Talk or Listen Address Received


7210 READIO 28

Return Command Pass Through.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


7210 READIO 30

Return Address Register 0.

Bit	Value	Meaning
7	128	Not Used
6	64	Disable Talker 0.
5	32	Disable Listener 0.
4-0	-	Interface Major Address


7210 READIO 32

Return Address Register 1.

Bit	Value	Meaning
7	128	EOI Sent on Last Data Byte
6	64	Disable Talker 1.
5	32	Disable Listener 1.
4-0	-	Interface Minor Address


7210 WRITEIO Registers

The following WRITEIO registers are supported.


7210 WRITEIO 3

Set Interrupt and DMA Enable.

Bit	Value	Meaning
7	128	Enable Interrupt
6-2	-	Unused
1	2	Enable DMA Channel 1
0	1	Enable DMA Channel 0


7210 WRITEIO 18

Set Bus Command & Data Lines.

Bit	Value	Meaning
7	128	DIO8
6	64	DIO7
5	32	DIO6
4	16	DIO5
3	8	DIO4
2	4	DIO3
1	2	DIO2
0	1	DIO1


7210 WRITEIO 20

Set Interrupt Mask Register 1.

Bit	Value	Meaning
7	128	Command Pass Through
6	64	Address Pass Through
5	32	Device Execute Trigger
4	16	End Received
3	8	Device Clear
2	4	Handshake Error
1	2	Data Out - Send Byte
0	1	Data In - Read Byte


7210 WRITEIO 22

Set Interrupt Mask Register 2.

Bit	Value	Meaning
7	128	Unused
6	64	SRQ Received
5	32	DMA Output - Transfer Data
4	16	DMA Input - Transfer Data
3	8	Command Output - Send Byte
2	4	Lockout Change
1	2	Remote Change
0	1	Address Status Change


7210 WRITEIO 24

Set Serial Poll Mode Response.

Bit	Value	Meaning
7	128	Device Dependent Status
6	64	1 - Send, 0 - Don't Send SRQ
5-0	-	Device Dependent Status


7210 WRITEIO 26

Set Address Mode Register.

Bit	Value	Meaning
7	128	Talk Only Mode
6	64	Listen Only Mode
5	32	Transmit/Receive Mode 1
4	16	Transmit/Receive Mode 0
3-2	-	Unused
1	2	Address Mode 1
0	1	Address Mode 0


7210 WRITEIO 28

Set Auxiliary Mode Register. Bits 7 to 5 determine which register is set. Bits 4 to 0 specify the value to write into the register. Tables giving the values for bits 4 to 0 for each auxiliary mode register follow the main table.

Bit	Value	Meaning
7	128	CNT2 - Control Code 2
6	64	CNT1 - Control Code 1
5	32	CNT0 - Control Code 0
4-0	-	COM4-COM0 - Command Codes 4-0

Auxiliary Command Register. If CNT2-CNT0 are set to 000 (binary), bits 4 to 0 are defined by the following values:

Auxiliary Command	SET	CLEAR
Immediate Execute pon	0	xx
Chip Reset	2	xx
Finish Handshake	3	xx
Trigger	4	xx
Return to Local	5	13
Send EOI	6	xx
Non-Valid/Valid 2nd Cmd./Add.	7	15
Parallel Poll Flag	9	1
Goto Standby	16	xx
Take Control Asynchronously	17	xx
Take Control Synchronously	18	xx
Take Control Synch. on End	26	xx
Listen	19	xx
Listen in Continuous Mode	27	xx
Local Unlisten 	28	xx
Execute Parallel Poll	29	xx
Send Interface Clear	30	22
Send Remote Enable	31	23
Disable System Controller	20	xx

Internal Counter Register. If CNT2-CNT0 are set to 001 (binary), bits 4 to 0 specify the State Change Prohibit Times.

Parallel Poll Register. If CNT2-CNT0 are set to 011 (binary), bits 4 to 0 have the following meaning:

Bit	Value	Meaning
4	16	Disables Participation in Parallel Poll
3	8	Logic Sense of Status
2-0	-	Data Line to Assert During Poll

Auxiliary Register A. If CNT2-CNT0 are set to 100 (binary), bits 4 to 0 have the following meaning.

Bit	Value	Meaning
4	16	Select 8-bit EOS length
3	8	Enable Transmit of EOS
2	4	Enable Receive of EOS
1	2	RFD Hold Off on End
0	1	RFD Hold Off on All Data

Auxiliary Register B. If CNT2-CNT0 are set to 101 (binary), bits 4 to 0 have the following meaning.

Bit	Value	Meaning
4	16	Indicates the Value of ist
3	8	Active Level of The INT Pin
2	4	Sets high speed as T(1)
1	2	Enable Transmit of END in Serial Poll
0	1	Enable Setting of CPT bit if Undefined Cmd.

Auxiliary Register E. If CNT2-CNT0 are set to 110 (binary), bits 4 to 0 have the following meaning.

Bit	Value	Meaning
4-2	-	Unused
1	2	Enable DAC Hold-Off by DCAS State
0	1	Enable DAC Hold-Off by DTAS State


7210 WRITEIO 30

Set Address Register.

Bit	Value	Meaning
7	128	Address Register 0 or 1
6	64	Disable Talk Function
5	32	Disable Listen Function
4-0	-	Primary Address of 0 or 1


7210 WRITEIO 32

Set End of String Register.

Bit	Value	Meaning
7-0	-	EOS Message Byte to Send


Statement Bus Action Summary

The following tables show the bus actions that take place when the various IEEE-488 control statements are executed. The table is broken down into System and Non-System Controller, then into Active and Non-Active Controller, and further subdivided into interface select code only or primary address specified. The mnemonics used in the tables are listed below:

ATN - Attention Line	PPD - Parallel Poll Disable
DCL - Device Clear	PPE - Parallel Poll Enable
EOI - End or Identify	PPU - Parallel Poll Unconfigure
GET - Group Execute Trigger	REN - Remote Enable
GTL - Go to Local	SDC - Selected Device Clear
IFC - Interface Clear	SPD - Serial Poll Disable
LAG - Listen Address Group	SPE - Serial Poll Enable
LLO - Local Lockout	TAG - Talk Address Group
MLA - My Listen Address	TCT - Take Control
MTA - My Talk Address	UNL - Unlisten
PPC - Parallel Poll Configure	UNT - Untalk


Abort GPIB Table
GPIB Action Table
ABORT


Clear GPIB Table
GPIB Action Table
CLEAR


Local GPIB Table
GPIB Action Table
LOCAL


Local Lockout GPIB Table
GPIB Action Table
LOCAL LOCKOUT


Pass Control GPIB Table
GPIB Action Table
PASS CONTROL


Ppoll GPIB Table
GPIB Action Table
PPOLL


Ppoll Configure GPIB Table
GPIB Action Table
PPOLL CONFIGURE


Ppoll Unconfigure GPIB Table
GPIB Action Table
PPOLL UNCONFIGURE


Remote GPIB Table
GPIB Action Table
REMOTE


Spoll GPIB Table
GPIB Action Table
SPOLL


Trigger GPIB Table
GPIB Action Table
TRIGGER


Serial (RS-232) I/O
Chapter 11
Serial (RS-232) I/O

This chapter describes the particulars of doing I/O on the serial (RS-232) interface. If you have not read the general discussion of I/O presented in the "General Input and Output" chapter, you should do so before reading this chapter. HTBasic requires a driver before the serial interface can be accessed. The Installing and Using manual explains how to load the SERIAL driver, how to prevent conflicts with a serial mouse, how to use more than two serial ports, and how to set driver switches.

This chapter describes the handshaking used for ENTER and OUTPUT, and shows how to select between hardware and software handshaking. A long discussion is presented on cabling, communication parameters, and data formats.  An in-depth, technical discussion of the RS-232 standard and its omissions is given. Pin assignments for standard connectors are listed. The register definitions for CONTROL, STATUS, READIO, WRITEIO, and the ENABLE INTR are presented.


General I/O

OUTPUT, ENTER, and TRANSFER are explained in the "General Input and Output" chapter. Before data can be exchanged, the serial driver must be loaded, the computer and device must be cabled together correctly (not any cable will work), and the RS-232 communications parameters must be set correctly on both the computer and the device.

The CONTROL and STATUS statements read or set various interface parameters, such as baud rate, character format, etc. CONTROL and STATUS examples given in this chapter assume that the serial interface has an ISC of 9. This is the default ISC for the first serial port. If you are using another port, or if you have changed the default ISC, you will use a value other than 9. The following example reads status register 3 of ISC 9.

PRINT "COM1 baud rate is ";STATUS(9,3)

The READIO and WRITEIO statements read or set hardware registers. These registers are typically quite different than the hardware registers on an HP BASIC RS-232 Interface. You should not attempt to use these registers unless you are familiar with the RS-232C hardware. You should also not mix use of READIO/WRITEIO with STATUS/CONTROL statements.  Using STATUS/CONTROL statements is preferred.


Handshaking

XON/XOFF handshaking capability, not available in HP BASIC, has been added to HTBasic. This capability is turned on by CONTROL 9,100;1 and turned off by CONTROL 9,100;0. It is on by default. XON is ^Q (DC1) and XOFF is ^S (DC3).

Hardware handshaking is also supported. It is turned on by

CONTROL 9,5;0   ! use DTR and RTS
CONTROL 9,12;0  ! read DSR, CD, and CTS
CONTROL 9,100;0 ! make sure XON/XOFF is disabled

It is turned off by

CONTROL 9,5;3     ! hold DTR and RTS active
CONTROL 9,12;176  ! ignore DSR, CD, and CTS
CONTROL 9,100;1   ! optionally enable XON/XOFF

By default, hardware handshaking is off.


ENTER Serial

To improve performance in receiving data, a 4096 byte receive buffer has been added in the DOS Version. The receive buffer provided in the Windows version is a 1024 byte buffer. Under UNIX the operationg system buffer is used. When a character is received on the serial interface, it is placed in the receive buffer. This is true regardless of the state of the BASIC program or hardware handshaking signals. The program need not be in an ENTER statement; nor must DSR or CD be active.

XON/XOFF Handshaking:
1. When the buffer is about full, XOFF is sent.
2. When there is room again in the buffer, XON is sent.

Hardware Handshaking:
1. If the receive buffer is empty, turn on DTR and wait for a character to arrive.
2. Get a character from the receive buffer and turn off DTR.


OUTPUT Serial

The following table outlines the steps used to OUTPUT data for software and hardware handshaking.

XON/XOFF Handshaking:
1. If an XOFF has been received from the device,
then the computer waits for an XON to be received.
2. The data is then sent.

Hardware Handshaking:
1. DTR and RTS are turned on. (In UNIX RTS only/DTR always on.)
2. The computer waits for the device to turn on DSR and CTS.
    (In the UNIX version CTS only.)
3. The data is then sent.
4. DTR and RTS are turned off.


Interrupt Support

The SERIAL driver supports ON INTR and ENABLE INTR. The definition of bits used in the ENABLE INTR statement is the same as for STATUS register 8, given at the end of this chapter. An example showing use of interrupts with the SERIAL driver is given in the "Interrupt" section of Chapter 7, "General Input and Output."

When an interrupt occurs, the serial interface hardware requires that it be acknowledged. To handle or acknowledge the different interrupts, you should do the following:

Interrupt	Acknowledge by...
Error Occurred	STATUS register 10, UART Line Status
Data Available	ENTER or STATUS register 6, Data In
Tx Reg Empty	STATUS register 9, Interrupt ID
Modem Status	STATUS register 11, Modem Status
( Registers 9 and 11 not available in UNIX.)


Connecting Devices to the Serial Interface

Interfacing computers, peripherals, and instruments with a serial interface is often difficult. Many users resort to consulting the local RS-232 "guru" to obtain the proper cables and parameters to make even a simple connection work correctly. Once connected and configured properly, things work well, but it is common to lose a whole day's labor getting a new connection to work.

While there is nothing wrong with consulting the local "guru," the following paragraphs attempt to explain a practical approach to interfacing with an RS-232 interface. An explanation is not made in every case as to why we do the things we do. For those interested, a technical discussion is given after the practical approach has been explained.

In the following discussion, we will use the following communications model:


"Standard" Cables

One approach to cabling is to have several types of cables around and when an interfacing situation arises, try them all out and see if one will work. This is not such a bad approach, so we present several common cable diagrams below. Your local computer store can probably assist you in purchasing several different types of cables, as well as gender changers to convert a male connector into a female and vice versa.

The documentation for the device you wish to communicate with may contain cable diagrams for hooking up the device to common computers. All but the "Straight Through" cable could be considered "Null Modem" cables because they attempt to make another non-modem device look like a modem. A phone call to the device manufacturer can also save a lot of time in determining what cable to use.


Cabling From the Ground Up

If you wish to identify a cable which should work in a particular application, it can be done using the straight forward method described here. First, examine the connectors on the computer and the device. The most common connector is a 25 pin DB connector, but you will also commonly see 9 pin DB connectors. Less commonly, you'll see connectors of all shapes and sizes. For the naive reader, a male connector has pins and a female connector has holes. Connectors almost always have identifying numbers near some of the pins/holes which give the pin numbers. The DB connector pins are arranged in two rows, with the first row having one more pin than the second. The pins are numbered beginning with pin 1 on the wider row. You will need to understand the pin numbering system used in the connectors only if you plan to make your own cable.

Once you have identified the type of connectors you will need, begin drawing a cable diagram using the steps in the following paragraphs. When your diagram is complete, match it with descriptions of the cables you have available. Then use, buy, or build the correct cable.

Pin 7 is usually the ground pin on a DB-25 pin connector (or pin 5 on a DB-9 connector). This can be verified by turning off and unplugging the computer, disconnecting any cables between it and other devices, and measuring with an ohm meter between the chasis and pin 7. The resistance should be zero. If pin 7 is not the ground, try pin 1, and then the other pins in turn until a ground is found. Do the same for the device and then start building your cable diagram by drawing a connection from the ground pin of the computer to the ground pin of the device.

The computer and the device each talk on one pin of the RS-232 connector and listen on another. Pins 2 and 3 (or pins 3 and 2 on a DB-9) are usually used for talking and listening, respectively; but this is not always the case. Turn the computer on and with a voltmeter, measure the voltage between the chasis of the computer and pin 2. Then do the same for pin 3. Ignore the polarity of the voltage, we are interested in the magnitude only. In the discussion that follows, we will refer to the larger voltage as the "transmitter" voltage and the smaller voltage as the "receiver" voltage. The computer talks on the pin with the transmitter voltage and listens on the other. Make the same measurement on the device. Then on your diagram, hook the talk pin of the computer to the listen pin of the device and vice versa.

You have now defined a "3-wire cable" and in some instances your cabling task is done. It's probably worth trying, because if you can use a 3-wire cable, you will save yourself a lot of headaches. If data is lost when using a 3-wire cable, try enabling software handshaking (XON/XOFF), explained earlier. With software handshaking turned on, transfer data using the FORMAT ON option of ASSIGN. If software handshaking can not be used on the device, you will need a hardware handshaking cable.

Let's continue defining a hardware handshaking cable. The three wires now hooked up are sufficient for transferring data. The goal now is to inform the computer and the device when each can and can not send data to the other. Said another way, we wish to prevent the sending of data while the other is not ready to receive it. We must identify on which pins each presents its "I'm ready" signal(s) and on which pins each asks "Are you ready?"

Get out your voltmeter again and measure pins 5, 6, and 8 (DB-9 pins 8, 6, and 1) on the computer. Remember that we are only interested in the magnitude. Some or all of them should have the "receiver" voltage. The ones that do are asking "Are you ready?" Now measure pins 5, 6, 8, and 20 on the device. One or more of these should have the "transmitter" voltage. If only pin 20 has it, it is the "I'm ready" pin of the device. If more than one of these pins have the "transmitter" voltage, then use 5 if possible as the "I'm ready" pin and any other if 5 is not possible. Draw a connection between all the "Are you ready?" pins of the computer to a single "I'm ready" pin of the device.

All of the pins 5, 6, 8, and 20 on the device that have the "receiver" voltage are the device's "Ready?" pins. Pin 20 (DB-9 pin 4) on the computer is usually the "Ready!" pin of the computer. On your cable diagram, draw a connection between the "Ready!" pin of the computer and the "Ready?" pins of the device.

Your cable diagram is now complete. Match it with descriptions of the cables you have available. Then use, buy, or build the correct cable. If this cable does not work, you should probably call the manufacturer of the device and get their help.


Communication Parameters

Plugging the cable between the computer and the device is not all that is required to make them talk. The devices must speak the same language in order to understand each other. It doesn't matter what it is, but it is essential they be the same! The language consists of the baud rate, data bits, parity, and stop bits. You must determine which of these parameters can be set on the device, what they can be set to, and how they are set. Typically, you would choose the highest baud rate that both the device and the computer support, one stop bit, eight data bits, and no parity.

To set these values on the computer running HTBasic, use the serial CONTROL registers 3 and 4, which are listed at the end of this chapter. For example, if you are using COM1 and the interface select code has not been changed from 9 and you wish to set 9600 baud, 1 stop bit, 8 data bits, and no parity, you would use this statement:

CONTROL 9,3;9600,3

Now plug in the cable, set the values, and give it a try. Remember to set the parameters on both the computer and the device. Depending on the device, you may have to set some switches, type a command, or do something else.


Data Formats

Once the computer and device are communicating correctly, it is still possible to get incorrect data if the data is formatted by the device in one way and interpreted by the computer in another or vice versa. The easiest way to get things working is to instruct the device to send data in ASCII, with CR/LF terminating each data item. However, the fastest way to exchange data is to do so in binary. Read the "General Input and Output" chapter carefully to determine how data is sent and how it is interpreted when it is received. As with communications parameters, it is important to set both the computer and the device to the same data format.


Interface Status Errors

An interface status error, Error 167, may occur when the cabling, communication parameters, or data formats are not correct. The error is not reported when it occurs but when you access the interface with ENTER or OUTPUT. To discover what the error was, execute the statement:

PRINT IVAL$(STATUS(9,10),2)

This reads the UART line status register. The meaning of the bits is

Bit	Value	Meaning
7	128	Not used
6	64	Transmit Shift Register Empty
5	32	Transmit Holding Register Empty
4	16	Break Detect
3	8	Framing Error
2	4	Parity Error
1	2	Overrun Error
0	1	Data Ready

Only bits 1 to 4 represent errors and bit 4 is not necessarily an error, if the device intended to get your attention by sending a BREAK indication. If several of the error bits are set, the meaning of the bits may not reflect the actual problem; you probably have the baud rate or character format set differently on the device and the computer. In UNIX versions, only bit 1 is supported the other bits are always zero.

If only a single error bit is set, the chances are good that the meaning of that bit reflects the actual error. A framing error indicates that the character did not end when it was supposed to. You probably have the number of data or stop bits set differently on the device and computer. A parity error means that the expected parity bit of the character was different than expected. You probably have the parity set differently on the device and computer. An overrun error means that a character was sent to the computer when the computer was not ready to receive it. You may not have handshaking set up correctly. You may not have executed the proper CONTROL statements, wired the cable correctly, or set up the device to handshake.

Keep in mind that RESET and SCRATCH will reset the communication parameters to the values specified with CONTROL registers 13 and 14. STATUS(9,3) and STATUS(9,4) may be used at any time to check the values of the baud rate and character format to see if they are what you expect.

Spurious interface status errors can be caused by turning the power to the computer or device on or off. To prevent an error on the ENTER or OUTPUT statement, the error can be cleared by STATUS(9,10) or by RESET 9.


RS-232: The Standard Non-Standard

The following is an in-depth technical discussion of the RS-232 standard and its weaknesses. You do not need to read it unless you wish a greater understanding of the standard and the issues involved, or if you have a particularly difficult cabling problem that you are attempting to solve.


The Standard

RS-232 (Electronic Industries Association Recommended Standard #232) describes a method of connecting a computer to an instrument by way of a communication channel, most often a modem attached to a phone line. The RS-232 standard has been revised four times. The current revision is called RS-232-D and was approved on November 12, 1986. The basic communications model is shown in this figure:

Computers, devices, instruments, terminals, or peripherals are called Data Terminal Equipment (DTE) since they terminate each end of the communications path. Modems are called Data Communications Equipment (DCE) since they facilitate the communication across the communication channel. (In RS-232-D, the term Data Communications Equipment has been replaced with the term Data Circuit-terminating Equipment.) The RS-232 standard describes the interface between the DTE and the DCE. The interface is made using a 25 pin D shell connector. The female connector is associated with the DCE and an interface cable with a male connector is offered by the DTE. The standard optionally allows this cable to be detachable from the DTE, however, no connector type is specified. Only the connection at the DCE is specified by the standard!


Pin Assignments for PC 25 and 9 pin connectors

25	9	Common
Pin	Pin	Mnemonic	Direction	Description
1	--	Shield	--	Shield
2	3	Tx	To	Transmit Data
3	2	Rx	From	Received Data
4	7	RTS	To	Request to Send
5	8	CTS	From	Clear to Send
6	6	DSR	From	DCE Ready
7	5	GND	Both	Signal Ground
8	1	CD	From	Carrier Detect
20	4	DTR	To	DTE Ready
22	9	RI	From	Ring Indicator

This table shows the pin assignments for the most often used pins. The direction of the signal is given to or from the DCE. The following paragraphs both define the commonly used pins and give a detailed chronological example of how they are used:

Shield - The shield of the cable should be connected to pin 1 on the DTE end only. Connecting it to both can create a ground loop that allows induced noise.

GND - Signal Ground - The signal ground is common to all the other data and control signals, going both to and from the DCE.

RI - Ring Indicator - Regardless of the state of DTR, if a ring is detected on the phone line, this signal should be turned on and off with each ring. This allows the DTE to count the number of rings and decide when to turn DTR on.

DTR - Data Terminal Ready - When this signal is on, it indicates to the modem that it has permission to answer the phone and establish a connection, should it ring, and should maintain the connection until DTR is turned off. When turned off, the modem should hang up and turn DSR off. DTR should not be turned back on until after DSR has been turned off. It is permitted by the standard that DTR be on any time the DTE is ready to send or receive data.

DSR - DCE (Data Set) Ready - When the DCE is ready to operate, and off hook, and the modem is not in voice mode and the modem has finished establishing a phone call, the DCE should turn DSR on. At this point data can be transferred over the modem. If a modem error occurs or a disconnect is detected, DSR should be turned off. The DTE should interpret this as an aborted connection and the next time DSR is turned on, it is considered a new call.

CD - Carrier Detect - When the modem is receiving the proper signals from the remote modem, it turns CD on. When DTR, DSR, and CD are all on, the DTE must be capable of receiving data at any time. When CD is off, no data will be received.

Rx - Received Data - The DTE receives data from the modem on this pin.

RTS - Request to Send - While the DTE must be willing to receive data anytime CD is on, it must ask permission to send data by turning RTS on.

CTS - Clear to Send - When the modem is ready to accept data, with DSR already on, it turns CTS on. If the modem is half-duplex, it also turns CD off to indicate that no data will be received while transmitting.

Tx - Transmitted Data - With DTR, DSR, RTS, and CTS all on, the DTE can transmit data on this line. When it is done transmitting, the DTE turns RTS off and then the modem turns CTS off.


The Non-Standard

The RS-232 standard has several major omissions. It does not specify the connector that should be used on the DTE if the required cable is detachable, and it does not specify how to connect two DTEs directly.

If the cable between the DTE and the DCE is detachable from the DTE, the standard only specifies the connector for the DCE end of the cable: a male 25 pin D shell connector. The connector for the DTE end of the cable is not specified. The RS-232 port on an IBM AT has a male 9 pin D shell connector. This is not in violation of the standard, so long as a cable is provided that makes a 25 pin D shell male connector available at the DCE end of the cable. The RS-232 port on a Hewlett-Packard 98626 Serial Interface has yet another type of connector.

It is however, a de-facto (i.e., "non-standard") standard to use a 25 pin D shell male connector on the DTE. Thus, the DTE to DCE cable has a female connector on one end, a male connector on the other, and corresponding pins in the connectors are connected "straight through:" pin 2 to pin 2, pin 3 to pin 3, etc.

While the RS-232 standard describes a straight forward method for connecting a DTE to a DCE (modem), it does not describe how to connect one DTE directly to another. Unfortunately, many people would like to connect a computer directly to an instrument — both DTEs. Individual manufacturers have addressed this problem in different ways, and have inadvertently created a lot of confusion. The general approach is to make each DTE think it is communicating with a DCE, thus preserving adherence to the RS-232 standard as much as possible. This can be done in several different ways, none of which are completely compatible with the standard.

The problem is that the standard assumes the communication channel is always slower than the DTE. Thus handshaking is present to prevent the DTE from writing too quickly to the DCE, but the standard contains no means for preventing the DCE from writing too quickly to the DTE. The only signal available for the DTE to use to tell the DCE it is not ready to accept data is DTR. But the standard specifies that "the OFF condition [of DTR] causes the DCE to be removed from the communication channel." Obviously, character handshaking with DTR is going to cause problems if the DCE hangs up between every character. Thus, although DTR is commonly used for handshaking, that use is not completely compatible with the standard.

A less common approach to hooking two DTEs together is to implement a full DCE interface in the instrument, plotter, or printer even though it is a data terminating equipment. Again, this is not completely compatible with the standard. The device must always be connected locally to the controlling computer (the DTE), but a standard DTE to DCE cable can then be used.


Pin Assignments

The following table gives the complete pin assignments for the RS-232 standard. "Cir" is the official RS-232 name for the circuit. "CCITT" gives the CCITT standard number for the circuit. ("Dir." is the direction of the circuit relative to the DCE.)

Pin	Circuit	CCITT	Dir.	Description
1	--	--	--	Shield
2	BA	103	To	Transmitted Data
3	BB	104	From	Received Data
4	CA	105	To	Request to Send
5	CB	106	From	Clear to Send

Pin	Circuit	CCITT	Dir.	Description
6	CC	107	From	DCE (Data Set) Ready
7	AB	102	Both	Signal Ground
8	CF	109	From	Recvd Line Signal (Carrier) Detect
9	--	--	--	Reserved for Testing
10	--	--	--	Reserved for Testing

11	--	--	--	Unassigned
12	SCF*	122	From	2nd Carrier Detect
13	SCB	121	From	2nd Clear to Send
14	SBA	118	To	2nd Transmitted Data
15	DB	114	From	Transmitter Timing (DCE)

16	SBB	119	From	2nd Received Data
17	DD	115	From	Receiver Timing (DCE)
18	LL	141	To	Local Loopback Test
19	SCA	120	To	2nd Request to Send
20	CD	108.2	To	DTE Ready

21	RL	140	To	Remote Loopback
22	CE	125	From	Ring Indicator
23	CH*	111	To	Rate Select (DTE Source)
24	DA	113	To	Transmit Timing (DTE)
25	TM	142	From	Test Mode

*CI, Rate Select (DCE Source), is assigned to pin 12 only if SCF is
not used. Otherwise it is assigned to pin 23.


Serial Registers

STATUS and CONTROL registers for the serial interface are given below.

READIO and WRITEIO registers for the PC serial interface are also given below. These registers are different than the hardware registers on an HP BASIC RS-232 Interface. The READIO/WRITEIO registers allow direct access to the interface hardware. You should not attempt to use these registers unless you are familiar with the PC RS-232C hardware. You should not mix use of READIO/WRITEIO with STATUS/CONTROL statements. Using STATUS/CONTROL statements is preferred. For documentation on the IBM Asynchronous Communications Adapter, please refer to the proper hardware Technical Reference manual, available from your local IBM or HP dealer.

The ON INTR and ENABLE INTR statements are supported by this interface. The values for the enable mask in the ENABLE INTR statement are the same as those for STATUS register 8, given below.


Serial CONTROL Registers

The following CONTROL registers are supported. When a table is given to explain the meaning of each bit, to calculate the value needed in the CONTROL statement add up the values in the Value column for each of the options needed.


CONTROL 0

Reset. The value must be non-zero.


CONTROL 1

BREAK. The value must be non-zero. A 400 millisecond BREAK signal is sent.


CONTROL 2

This register is undefined in both HTBasic and HP BASIC.


CONTROL 3

Set baud. The baud rate is set to the value you specify. Available baud rates are 110, 300, 600, 1200, 2400, 4800, 9600, 14400, and 19200. Under 32-bit Windows, 38400, 57600, and 115200 are also available.


CONTROL 4

Set character format.

Bits	Value	Meaning
7-6	-	Not used.
5,4,3	56	Parity bit is always Zero. (111)
40	Parity bit is always One. (101)
24	Parity is Even. (011)
8	Parity is Odd. (001)
0	No parity is sent. (000)
2	4	2 stop bits (1.5 for 5 bit characters).
0	1 stop bits.
1,0	3	8 bit. (11)
2	7 bit. (10)
1	6 bit. (01)
0	5 bit. (00)


CONTROL 5

Set hardware handshaking output line state.

Bit	Value	Meaning
7-5	-	Not used.
4	16	16=Enable, 0=Disable Loopback Testing.
3	8	Not used. (2nd-RTS not supported).
2	4	Not used. (DRS not supported).
1	2	2=Tie RTS high, 0=Use RTS in handshaking.
0	1	1=Tie DTR high, 0=Use DTR in handshaking.
(DTR is ignored in the UNIX version.)


CONTROL 6

Data Out. The specified character is loaded into the transmit holding register and then transmitted. Handshaking lines are not changed or read. Normally, you should use the OUTPUT statement.


CONTROL 7

Optional Receiver/Driver Status. On this interface, this is ignored.


CONTROL 8 to 11

These registers are undefined in both HTBasic and HP BASIC.


CONTROL 12

Set hardware handshaking input line state.

Bit	Value	Meaning
7	128	128=Ignore CD, 0=Use CD in handshaking.
(CD is ignored in the UNIX version.)
6	64	Not used.
5	32	32=Ignore DSR, 0=Use DSR in handshaking.
(DSR is ignored in UNIX and with SERIAL32.)
4	16	16=Ignore CTS, 0=Use CTS in handshaking.
3-0	-	Not used.


CONTROL 13

Set default baud. Each time HTBasic is started, the default is set to 9600. This register can not be used to change that. This register can be used to change the default set by SCRATCH or RESET.


CONTROL 14

Set default character format. Each time HTBasic is started, the default is set to Parity disabled, 1 stop bit, 8 data bits. This register can not be used to change that. This register can be used to change the default set by SCRATCH or RESET.


CONTROL 100

XON/XOFF Handshaking. A non-zero value enables XON/XOFF. A zero value disables it. By default it is on.


Serial STATUS Registers

The following STATUS registers are supported.


STATUS 0

Card identification. Returns a 66. This is the same value returned by the HP 98644 Serial Interface. It signifies that the following differences from the HP 98626 Interface are present:

1. The optional receiver/driver lines are not present.
    Register 7 does nothing.
2. Configuration switches are not present. Defaults are
    9600 baud, 8 bit, no parity on a PC. The defaults are the
    system settings on UNIX versions.
3. The physical connector is a RS-232-C 9 or 25 pin connector.


STATUS 1

Interrupt Status. If you will be porting programs to an HP BASIC computer, you should be aware that bits 5 to 0 are defined differently under HP BASIC. Only bits 5 and 4 give the interrupt number, encoded to specify an interrupt in the range 3 to 6. Also, a bug in HP BASIC can cause bit 6 to be asserted after a DISABLE INTR has supposedly disabled the interrupt. This does not occur with HTBasic. Bits 5 through 0 are zero on UNIX versions and bit 6 is a 1 for a pending interrupt on the Windows version.

Bit	Value	Meaning
7	128	Interrupts Enabled
6	64	Interrupt waiting service
5-2	-	Interrupt number, 0-15
1,0	-	Not used.


STATUS 2

Interface Activity Status. Bit 2 is always zero in this implementation because HTBasic stops handshaking whenever a function call may occur.

Bit	Value	Meaning
7-3	-	Not used.
2	4	Handshake in progress (always 0).
1	2	Interrupts Enabled (ENABLE INTR).
0	1	Not used.


STATUS 3

Baud rate.


STATUS 4

Character format (See CONTROL above).


STATUS 5

Read hardware handshaking output line state (See CONTROL above).


STATUS 6

Data In. Reads next character from the receive buffer. The character is then removed from the buffer. If no characters are in the buffer, the character in the UART receive buffer is returned.


STATUS 7

Optional Receiver/Driver Status. On this interface, this is always zero.


STATUS 8

Interrupt Enable Mask. This register is set with the ENABLE INTR statement.

Note: It is recommended that bit 1, Interrupt if Tx Holding Reg. Empty, not be used because any time ENABLE INTR is executed, this register will be empty and the interrupt will immediately occur. The interrupt-driven receive buffer code will then immediately acknowledge the interrupt as a side effect of checking for data in the receiver.

Bit	Value	Meaning
7-4	-	Not used.
3	8	Interrupt if Modem Status (register 11) changes.
2	4	Interrupt on error (register 10, bits 1 to 4).
1	2	Interrupt if Transmit Holding Reg Empty.
0	1	Interrupt if data becomes available.


STATUS 9

Current Interrupt ID. If bit 0 is 0, then an interrupt is pending, and bits 2 and 1 indicate the cause. The interrupts are prioritized by value. Multiple interrupts can be pending. An interrupt handler should read this register repeatedly, handling each interrupt until this register shows that no interrupt is pending. Also, if a Data Available interrupt is followed by an Error Occured interrupt before either is serviced, only the later will be reported. This is different than HP BASIC. If you enable both interrupts, and an Error interrupt occurs, you should manually check for data available using bit 0 of register 10. Only Data Available is supported in the UNIX versions.

Bit	Value	Meaning
7-3	-	Not used.
2,1	6	Error Occurred (register 10, bits 1 to 4)(11).
4	Data Available (10).
2	Transmit Holding Register is empty (01).
0	Modem Status (register 11) changed (00).
0	1	1=No interrupt, 0=Interrupt pending.

To handle, or acknowledge an interrupt, you should do the following:

Interrupt	Acknowledge by...
Error Occurred	STATUS register 10, UART Line Status.
Data Available	ENTER or STATUS register 6, Data In.
Tx Reg Empty	STATUS register 9, Interrupt ID.
Modem Status	STATUS register 11, Modem Status.


STATUS 10

UART line status. Only Data Ready is supported in the UNIX versions.

Bit	Value	Meaning
7	128	Not used.
6	64	Transmit Shift Register Empty.
5	32	Transmit Holding Register Empty.
4	16	Break Detect.
3	8	Framing Error.
2	4	Parity Error.
1	2	Overrun Error.
0	1	Data Ready.


STATUS 11

Modem status. This register is not supported in UNIX versions.

Bit	Value	Meaning
7	128	Carrier Detect (CD).
6	64	Ring Indicator (RI).
5	32	Data Set Ready (DSR).
4	16	Clear to Send (CTS).
3	8	Delta Carrier Detect.
2	4	Trailing Edge Ring Indicator.
1	2	Delta Data Set Ready.
0	1	Delta Clear to Send.


STATUS 12

Return the hardware handshaking (input lines) state. See CONTROL register 12, above.


STATUS 13

Return the current default baud rate.


STATUS 14

Return the current default character format.


STATUS 100

Return the XON/XOFF enable state. 1 - enabled, 0 - disabled.


STATUS 101

Return the number of characters in the receive buffer.


Serial READIO Registers

Note that registers 0 and 1 are used to access the Divisor Latch in addition to other UART registers. If the Divisor Latch Access Bit (DLAB) of the Line Control Register (register 3) is set, then registers 0 and 1 access the Divisor Latch. Register 0 accesses the least significant byte and register 1 the most significant. To calculate the divisor needed for a particular baud rate, use the formula Divisor = 115200 DIV Baud_rate. If DLAB is clear, then registers 0 and 1 access the UART registers given below. READIO is not supported in the UNIX and Windows versions.


READIO 0

Receive Buffer (if DLAB is 0) and Divisor Latch, least significant byte (if DLAB is 1).


READIO 1

Interrupt Enable Register (if DLAB is 0). Interrupt Enable Register bit definitions are:

Bit	Value	Meaning
7-4	-	Not used.
3	8	Enable Modem Status interrupt.
2	4	Enable receive line status Interrupt.
1	2	Enable Transmit Holding Register empty
interrupt.
0	1	Enable data available interrupt.


READIO 2

Interrupt Identification Register.

Bit	Value	Meaning
7-3	-	Not used.
2,1	6	Receiver line status (11).
4	Data Available (10).
2	Transmit Holding Register empty (01).
0	Modem Status (00).
0	1	1=No interrupt, 0=Interrupt pending.


READIO 3

Line Control Register.

Bits	Value	Meaning
7	128	Divisor Latch Access Bit (DLAB).
6	64	Set Break.
5,4,3	56	Parity bit is always Zero. (111)
40	Parity bit is always One. (101)
24	Parity is Even. (011)
8	Parity is Odd. (001)
0	No parity is sent. (000)
2	4	2 stop bits (1.5 for 5 bit characters).
0	1 stop bits.
1,0	3	8 bit. (11)
2	7 bit. (10)
1	6 bit. (01)
0	5 bit. (00)


READIO 4

Modem Control Register.

Bit	Value	Meaning
7-5	-	Not used.
4	16	16=Enable, 0=Disable Loopback Testing.
3	8	Gate interrupts (OUT 2).
2	4	Not used (OUT 1).
1	2	Request to Send (RTS).
0	1	Data Terminal Ready (DTR).


READIO 5

Line Status Register.

Bit	Value	Meaning
7	128	Not used.
6	64	Transmit Shift Register Empty.
5	32	Transmit Holding Register Empty.
4	16	Break Detect.
3	8	Framing Error.
2	4	Parity Error.
1	2	Overrun Error.
0	1	Data Ready.


READIO 6

Modem Status Register.

Bit	Value	Meaning
7	128	Carrier Detect (CD).
6	64	Ring Indicator (RI).
5	32	Data Set Ready (DSR).
4	16	Clear to Send (CTS).
3	8	Delta Carrier Detect.
2	4	Trailing Edge Ring Indicator.
1	2	Delta Data Set Ready.
0	1	Delta Clear to Send.


Serial WRITEIO Registers

Note that registers 0 and 1 are used to access the Divisor Latch in addition to other UART registers.  If the Divisor Latch Access Bit (DLAB) of the Line Control Register (register 3) is set, then registers 0 and 1 access the Divisor Latch.  Register 0 accesses the least significant byte and register 1 the most significant.  To calculate the divisor needed for a particular baud rate, use the formula Divisor = 115200 DIV Baud_rate.  If DLAB is clear, then registers 0 and 1 access the UART registers below. WRITEIO is not supported in the UNIX and Windows versions.

0 - Transmit Holding Register (if DLAB is 0).

1 - Interrupt Enable Register (if DLAB is 0).

3 - Line Control Register.

4 - Modem Control Register.

5 - Line Status Register.

6 - Modem Status Register.


Serial ENABLE INTR Mask

ON INTR and ENABLE INTR are supported on this interface. The definition of bits used in the ENABLE INTR statement is given above under STATUS register 8.


Other I/O Destinations/Sources
Chapter 12
Other I/O Destinations/Sources

This chapter discusses I/O (input/output) facilities for  buffers, strings, a special interface called the "Processor Interface," and pipes. This chapter also describes methods for using interfaces and devices for which there is no HTBasic device driver.

Chapter 7, "General Input and Output," discussed the general principles used for input/output. These principles apply to all I/O targets. In particular, use of ASSIGN, OUTPUT, ENTER, STATUS, CONTROL, and TRANSFER were explained. If you have not yet read that chapter, you should do so before reading this one. Chapter 8, "CRT, Keyboard, and Printer" contains information on statements that are especially useful for printer use, and should be read in connection with the Parallel Interface information in this chapter.


I/O to Strings

The OUTPUT and ENTER statements can be used to write or read data to or from a string. This capability is convenient when you wish to capture the output for further manipulation, or when converting between different formats.


OUTPUT to Strings

Output to strings starts at the beginning of the string with each OUTPUT statement, outputs the data into the string in FORMAT ON format, and then sets the string length. A second OUTPUT statement will overwrite the information from the first.

10 OUTPUT A$;"1"
20 OUTPUT A$;"2"
30 PRINT A$="2"&CHR$(13)&CHR$(10)
40 END

This program shows that the second output overwrites the data from the first. It also illustrates that the normal item and line terminators are output to the string unless suppressed.

OUTPUT to a string with the "W" image specifier writes binary data to a string. The data is always written using the native byte ordering of the computer system. Intel processors use LSB FIRST ordering. Motorola 68xxx, Sun SPARC, and HP PA-RISC processors use MSB FIRST ordering.


ENTER from Strings

ENTER from strings starts at the beginning of the string with each ENTER statement, reads the data from the string with FORMAT ON, and returns an EOI signal with the last character of the string.

10 A$="12"&CHR$(10)&"34"
20 ENTER A$;B$
30 ENTER A$;C$
40 PRINT B$,C$

In this program, both B$ and C$ will have the value "12", even though the first ENTER did not read all the data from the string. With strings, each ENTER re-starts from the beginning of the string.

ENTER from a string with the "W" image specifier reads binary data from a string. The data is always read using the native byte ordering of the computer system, as explained previously in the "OUTPUT to Strings" section.


Buffers

I/O to strings, as explained above, has limited application. Buffer I/O is more powerful. HTBasic implements circular buffers. Fill and empty pointers remember where the last OUTPUT, ENTER, or TRANSFER ended, allowing the next statement to pick up where the last one left off. The ASSIGN statement sets up a buffer for I/O. While buffers can be created in strings or arrays (named buffers), unnamed buffers are recommended. The statement

ASSIGN @Iopath TO BUFFER [300]

creates an unnamed buffer and assigns it an I/O path name. The

ASSIGN @Another TO BUFFER X(*)

statement assigns an I/O path name to a variable previously declared as a buffer in a COM, DIM, INTEGER, or REAL statement.

The buffer specified in ASSIGN may now be used in ENTER, OUTPUT, and TRANSFER statements. Information kept about a BUFFER includes the current number of bytes in the buffer (initially set to 0), the empty and the fill pointers (initially set to 1), the buffer capacity, and TRANSFER information.

If somehow a BUFFER ceased to exist while the I/O path used to write to it still existed, fatal errors could result. For this reason, the BUFFER lifetime must equal or exceed the I/O path lifetime. The following table shows the legal and illegal combinations of BUFFERs and I/O paths. A value of 0 means the combination is legal. A non-zero value gives the error returned if this combination is used.

Type of	               Type of I/O Path
BUFFER	Local	COM	Parameter
Local	0	602	602
Same COM	-	0	-
Different COM	-	602	-
Parameter	0	602	0*
Un-named	0	602	602
ALLOCATE	603	603	603
Not a BUFFER	603	603	603

*If the I/O path and BUFFER parameters have been passed through multiple CALL levels, the BUFFER must outlive the I/O path. Also, if a parameter originated as a COM variable, the rules for COM variables apply.

Unnamed buffers can only be accessed through their I/O path. Named buffers can be directly accessed through their variable's name, but this procedure is not recommended since the data in the buffer is unformatted, the data may have the wrong byte order, and direct access does not automatically update the buffer registers. The data in the buffer and the string's current length can be changed, but the buffer registers (empty and fill pointers, current-number-of-bytes register) are not automatically updated. To automatically update the buffer registers use ENTER, OUTPUT, and TRANSFER statements.


BUFFER STATUS/CONTROL Registers

The STATUS and CONTROL registers of an I/O path assigned to a BUFFER were presented in full in Chapter 7. The following example shows use of registers 2 through 5. All of these registers can be read, and all but the first can be set.

10   ASSIGN @Io TO BUFFER [1000];FORMAT OFF
20   Info("Start",@Io)
30   OUTPUT @Io;PI,1/3
40   Info("After OUTPUT",@Io)
50   ENTER @Io;X
60   Info("After ENTER",@Io)
70   END
80   SUB Info(When$,@Io)
90     PRINT When$
100    PRINT "  Total buffer size is    ";STATUS(@Io,2)
110    PRINT "  Fill pointer is         ";STATUS(@Io,3)
120    PRINT "  # of bytes in buffer is ";STATUS(@Io,4)
130    PRINT "  Empty pointer is        ";STATUS(@Io,5)
140  SUBEND

This program produces the following output:

Start
  Total buffer size is     1000
  Fill pointer is          1
  # of bytes in buffer is  0
  Empty pointer is         1
After OUTPUT
  Total buffer size is     1000
  Fill pointer is          17
  # of bytes in buffer is  16
  Empty pointer is         1
After ENTER
  Total buffer size is     1000
  Fill pointer is          17
  # of bytes in buffer is  8
  Empty pointer is         9


Pipes

Under UNIX, OUTPUT and ENTER can be made through pipes to exchange data with other programs or to read the output of an operating system command. The ASSIGN statement is used to spawn a child process running a different program or command and establish an I/O path to communicate with that process. The string specifying the command must start and/or end with the pipe character, the vertical bar, "|".

If the string begins with "|", then OUTPUT can be used to send information to the process. If the string ends with "|", then ENTER can be used to get information from the process. To close the pipe, close the I/O path by assigning it to "*". The following example runs the "whoami" command, reads the output from the command, and prints it on the screen. The pipe is then closed.

10    ASSIGN @I TO "whoami |"
20    ENTER @I;A$
30    PRINT "You are logged in as ";A$
40    ASSIGN @I TO *
50    END


The Processor Interface (32)

Interface select code 32 has a special usage and cannot be changed. It allows some system attributes associated with the computer processor to be set or read. CONTROL and STATUS are the only operations allowed on this interface. To ease porting of HP BASIC programs, CONTROL operations are supported, but are ignored except as noted. The following STATUS registers are supported in this version.


STATUS 0

Parity Checking. Always 1 (enabled), regardless of the presence or absence of and state of parity checking.


STATUS 1

External Cache. Always 0 (disabled), regardless of the presence or absence and state of an external cache.


STATUS 2

Floating-Point Math Hardware. If a math coprocessor is present, and enabled, a one is returned. If no math coprocessor is present, or if one is present and disabled, then zero is returned.

When using HTBNO387 (DOS Version), a zero can be written to this register to disable the coprocessor. This should not be done with HTB386. The control statement looks like this:

CONTROL 32,2;0


STATUS 3

Internal (Inside the Processor) Cache. Always 0 (disabled) in all versions but the DOS Version, where it reflects the actual enabled/disabled state of the internal processor cache.


STATUS 4

Battery-Backed-Up Clock Type. Presently, always 1.

0 = Battery-backed-up clock is NOT present.
1 = Battery-backed-up clock is present.


Accessing Other Interfaces and Devices

If available, an HTBasic device driver is the best way to access a device, interface, or plug-in board. An HTBasic device driver is loaded only while HTBasic is running and so does not consume any memory when not needed. In the DOS Version, HTBasic device drivers are automatically loaded into extended memory when necessary, alleviating DOS memory shortages. An HTBasic driver also has STATUS and CONTROL registers that facilitate the set up and use of the board.

However, sometimes it is necessary to access a device for which there is no HTBasic driver. The approach differs depending on the operating system. Sections are given below for DOS and for UNIX.


Under DOS

Depending on the software that was supplied with the board, accessing the board can be accomplished in three different ways:

1. IN, OUT, PEEK, and POKE operations
2. OBJ or LIB Calls
3. DOS Device Driver


DOS IN, OUT, PEEK, and POKE operations

ALL boards can be accessed by IN, OUT, PEEK, or POKE operations. In some instances this is the only way to access a board. The following statements accomplish these operations:

INP(port)                   ! Input a byte
INPW(port)                  ! Input a word
OUT port, byte              ! Output a byte
OUTW port, word             ! Output a word
READIO(9826, address)       ! PEEK byte
READIO(-9826, address)      ! PEEK word
WRITEIO 9826,address;byte   ! POKE byte
WRITEIO -9826,address;word  ! POKE word

These statements are explained in more detail in the Reference Manual or in Chapter 7, "General Input and Output," of this manual.

For example, a Keithley/MetraByte DAC-02 12-bit Analog Output Board comes with no OBJ, LIB, or DOS device driver. Because of the simplicity of use, it is intended that you use OUT instructions to control the board. The following programming example is provided by the manufacturer:

10  INPUT "Enter the data from 0 to 4095 ",D
20  Dh=INT(D/16)
30  Dl=D-16*Dh
40  Dl=16*Dl
50  OUT &H330,Dl
60  OUT &H331,Dh
70  GOTO 10
80  END

With HTBasic, it is possible to output all 12 bits at once. The DAC-02 requires the bits to be left justified. The following statement will accomplish the same thing as the last example:

OUTW &H330,SHIFT(D,-4)


DOS OBJ or Library Calls

Some boards are supplied with OBJs or LIBs that can be linked with particular programming languages to facilitate use of the board. For example, a Keithley/MetraByte DAS-16 A/D Board comes with a library of routines accessed via "Calls" from BASICA such as

CALL DAS16(MD%,DIO%(0),FLAG%)

A library designed for use with one programming language usually doesn't work with all programming languages. In particular, a BASICA or QuickBASIC library can not be called directly from HTBasic. You may, however, write the portions of the program that access the board in a language for which a library is supplied, and then use the HTBasic EXECUTE statement to call those portions as subroutines of HTBasic. This method is described in Chapter 14, "Mixed Language Programming."

If this method does not meet your requirements, look at options 1 and 3. Since all boards are accessible by IN, OUT, PEEK, or POKE operations, you can access the board at that level (provided the manufacturer has provided or is willing to provide documentation for the IN/OUT registers of the board). Another option is to use a DOS device driver for the board, if the manufacturer makes one available. DOS device drivers are discussed next.


DOS Device Driver

Some boards are supplied with a DOS device driver that can be accessed from most any programming language, as well as most application programs. The driver is installed in your CONFIG.SYS and when your computer is booted, the driver is added to the drivers already present in DOS. The board is then accessed using the same statements used to access a file. The DOS device driver has a name that you use instead of a filename. Any file I/O to that name will go to the board instead of a file.

For example, the Keithley/MetraByte DAS-50 A/D Board comes with a DOS device driver that creates a DOS device named "$DAS50". The following example, provided by the manufacture, is translated from QuickBASIC to HTBasic:

10    ASSIGN @I TO "$DAS50";FORMAT ON
30    ON END @I GOSUB 1000
40    INPUT "Enter Sample rate required ",X
50    OUTPUT @I;"Set Rate ";X;" ch 0&1 samples 1000 range 5v"
      . . .  .
      . . .  .
100   STOP
1000  REM To retrieve error one must read from the device
1010  ENTER @I;N,A$
1020  PRINT A$
      . . .  .
      . . .  .
1030  ERROR RETURN
5000  END


Under UNIX

Under UNIX, devices are available to any programming language and most application programs as names in the file system. The driver is linked into the operating system before the computer was shipped to you, or afterwards as part of the device's installation procedure. When UNIX boots, the driver is brought into memory. The device is then accessed using the same statements used to access a file. The device has a name that you use instead of a filename. Any file I/O to that name will go to the device instead of a file.

Device names are typically found in the /dev directory, or a subdirectory of /dev. For example, the serial ports on a SPARCstation 2 running SunOS 4.x are called /dev/ttya and /dev/ttyb. Serial ports under HP-UX are similarly named.

10   ASSIGN @S1 TO "/dev/ttya";FORMAT ON
20   OUTPUT @S1;"MEASURE:VOLT?"
30   ENTER @S1;V
40   END

Just as with a file, you must have the proper permissions to access a device. In the case of serial ports, it is also important that the port not be enabled for login. Refer to your system documentation or system administrator for more information.


Use Pipes

Under UNIX, it is also possible to write a program in another language and establish a pipe to output/enter data to/from the other program. This approach may be useful if a library of routines to access the device is supplied for the C language. Write just the portions of the program that call the libraries in C, and then read commands from HTBasic from stdin and write output for HTBasic to stdout.


International Language Support
Chapter 13
International Language Support

This chapter describes HTBasic international language support. HP BASIC is fairly tightly tied to the Roman-8 character set. HTBasic is not tied to any given character set.  HTBasic depends on the operating system for keyboard, display, and printer support of different character sets. HTBasic provides support for collation or lexical ordering and upper- and lowercase conversions. Users are encouraged to use the character sets supported by the operating system. The use of Roman-8 is discouraged when it is not supported by the operating system.

This chapter describes handling attribute/color character conflicts, LEXICAL ORDER (collating sequence), upper/lowercase conversions, LABEL characters, and user-defined lexical order rules. Limited Roman-8 character set support is explained. Lexical order and character set tables are given at the end of the chapter.


DOS Code Pages

Under DOS, character set support is provided through "Code Pages." A code page is simply a character set. Starting with DOS 3.3, international language support was included with DOS using code pages. Code page support is included for keyboards, displays, and printers. A synopsis of commands necessary to install code page support is given later in this chapter.

The Japanese version of DOS HTBasic runs under DOS/V. The proper character set support should have been loaded when DOS/V was installed on the computer. This support is accessed by HTBasic through the VGAB screen driver.


Windows and Unix Character Sets

Under Windows and Unix, character sets are supported through printer and screen fonts and keyboard input methods. The correct combinations of fonts and input methods are usually installed as part of the system installation.


Character Sets

ASCII is one of the most widely used character sets, but unfortunately, defines characters only up to CHR$(127) and excludes many characters necessary in languages throughout the world. Other character sets define characters up to CHR$(255) and include other necessary characters. The following paragraphs describe several of these character sets. Each version of HTBasic has built-in support for one character set, but the capability is present for users to add support for other character sets.

 Japanese-enabled versions of HTBasic, when run in Japanese mode, allow use of two-byte characters using the ISO-932 and Shift-JIS character sets. These are explained later in this chapter.

Character set tables for code pages 850, 437, Roman-8, Latin-1, ISO-932 and an overview of the Shift-JIS character set are given at the end of this chapter.


Code Pages 437 and 850

The default DOS character set is named code page 437. Code page 437 lacks many characters necessary for European languages. Code page 850 is a character set designed with all the characters needed for most European, North American, and South American languages. It is a superset of code page 437. It replaces some of the table-drawing and Greek characters in code page 437 with additional international characters.

The DOS version of HTBasic expects code page 850 to be in use. If it is not, the keyboard may not match the display and upper- and lowercase conversions and collating may not function as expected. If code page 437 is in use, conversions will work correctly unless a conversion produces a character that is not in code page 437.


Roman-8

The HP BASIC Series 200/300 character set is named Roman-8. It is available on the popular LaserJet printer, but is not implemented in a DOS code page. The DOS version of HTBasic provides a solution for users wishing to use the Roman-8 character set. This solution works only while HTBasic is running, and is discussed later in this chapter.

The HP 700 Workstation Version of HTBasic expects the Roman-8 character set to be in use. If it is not, the keyboard may not match the display and upper- and lowercase conversions and collating may not function as expected.


Latin-1

The character set used by the Sun SPARCstation and by Microsoft Windows is called Latin-1 or ISO 8859-1. Most X Windows systems from vendors other than HP also use this character set.

The Sun SPARCstation and Windows versions of HTBasic expect the Latin-1 character set to be in use. If it is not, the keyboard may not match the display and upper- and lowercase conversions and collating may not function as expected.


ISO-932 and Shift-JIS

All Japanese-enabled versions of HTBasic use the ISO-932 single-byte and Shift-JIS character double-byte sets for character representation when run in Japanese mode.  These are the same character sets used by HP BASIC. The ISO-932 character set is the same as the ASCII set for characters whose values are less than 128.  Characters whose values are between CHR$(129) and CHR$(159) or between CHR$(224) and CHR$(252) are used as leading bytes for two-byte characters using the Shift-JIS character mapping.  Characters whose values are between CHR$(161) and CHR$(223) are half-width katakana characters from the ISO-932 character set. CHR$(160) is a space. CHR$(128) and CHR$(253) - CHR$(255) are undefined.

Non-ASCII characters are entered into HTBasic programs using the operating system's Input method. ASCII, katakana, and hiragana characters are entered using the normal keyboard keys together with special shift keys. Kanji are usually entered by allowing the user to type a phonetic (ASCII, katakana, or hiragana) representation of the desired character on the keyboard and pressing a convert key, which displays a list of possible characters at the bottom of the screen or in a separate window. The user then chooses the desired character from the list.


Variable Names

HP BASIC limits the international characters in variable names to CHR$(161) to CHR$(254). In HTBasic, this range is expanded to CHR$(128) to CHR$(254) since many commonly used characters are in the range excluded by HP BASIC. In Japanese mode, HTBasic allows characters in the range CHR$(161) - CHR$(223) (single-width katakana characters) in variable names.


Attribute Character Conflict

HP BASIC uses the range CHR$(128) to CHR$(143) for attribute and color control characters. This range is used by some character sets for various international characters. To allow use of characters in this range, HTBasic will move attribute and color control characters from this range to CHR$(16) to CHR$(31) with the statement:.

CONTROL CRT,100;1

To restore the normal range, use

CONTROL CRT,100;0

When HTBasic is run in Japanese mode, CONTROL CRT,100;1 is executed automatically.

CONTROL CRT,100 does not affect values used with CONTROL registers, only values PRINTed or OUTPUT to the CRT. This statement is an enhancement to HP BASIC and will return an error if executed on a Series 200/300 computer.

The following table shows the attribute and color control characters for both the normal and alternate ranges. Remember that not all attributes are supported on every display.

Attribute	Normal	Alternate
None	128	16
Inverse	129	17
Blinking	130	18
Inverse & Blinking	131	19
Underline	132	20
Underline & Inverse	133	21
Underline & Blinking	134	22
Underline, Inverse, & Blinking	135	23

Attribute	Normal	Alternate
White	136	24
Red	137	25
Yellow	138	26
Green	139	27
Cyan	140	28
Blue	141	29
Magenta	142	30
Black	143	31


Lexical Order

"Lexical order" is another term for "alphabetical order". A "lexical order" defines an ordering of each character in a character set. By assigning an order number to each character, strings can be compared in a meaningful way with "<", ">", and MAT SORT. Different languages have different lexical orders.

The statement LEXICAL ORDER IS can be used to specify lexical order rules. The current LEXICAL ORDER is returned by the SYSTEM$("LEXICAL ORDER IS") function.

Rules for five languages are built into HTBasic: ASCII, FRENCH, GERMAN, SPANISH, and SWEDISH. (In HTBasic, LEXICAL ORDER IS STANDARD is equivalent to LEXICAL ORDER IS ASCII). These languages are inclusive enough to support most ordering conventions. If the language you are using is not listed, check the LEXICAL ORDER tables near the end of this chapter to see which most nearly matches your language. You may define your own ordering rules as explained later in this chapter.

In Japanese mode, HTBasic defaults to LEXICAL ORDER IS STANDARD.

You must have the correct character set active for the built-in rules to function correctly. The character set expected by each version of HTBasic was presented previously in this chapter. Limited support for Roman-8 on operating systems that don't support it is explained later in this chapter.

Execute one of the following statements to specify lexical ordering rules:

LEXICAL ORDER IS ASCII
LEXICAL ORDER IS FRENCH
LEXICAL ORDER IS GERMAN
LEXICAL ORDER IS SPANISH
LEXICAL ORDER IS SWEDISH


Upper and Lowercase Conversions

The LEXICAL ORDER IS statement also determines upper/lowercase conversions in addition to ordering rules. Rules for the built-in languages are given in the table below. Note that   (uppercase Y umlaut) does not exist in codepage 437, 850 or the Latin-1 character sets. In these cases, Y is used for UPC$("ÿ").

You may define rules for other languages using "LEXICAL ORDER IS Array(*)", which has been enhanced to allow case conversion rules to be stored in the array along with order rules. HP BASIC does not support these enhancements but does not return an error if they are present. These enhancements are explained later under "User-Defined UPC$/LWC$ Rules".

In Japanese mode, uppercase and lowercase conversion is limited to ASCII characters; Japanese characters are not converted.


Japanese Character Conversions

In Japanese mode, HTBasic supports converting between hirigana and double-width katakana and between single- and double-width katakana and single- and double-width Roman characters. This support is accessed through the CVT$ command.


LABEL Character Set

One limitation of most operating system character set support is that it does not contain vector definitions of the characters for the LABEL statement. Also, like HP BASIC, the HTBasic LABEL statement does not support all the international language characters above CHR$(127). But unlike HP BASIC, HTBasic has been enhanced to allow the user to define his own characters, or delete existing characters. The characters that are defined by default are:

Char	Latin-1	PC-850	Roman-8
ü	252	129	207
é	233	130	197
â	226	131	192
ä	228	132	204
à	224	133	200
å	229	134	212
ç	231	135	181
ê	234	136	193
ë	235	137	205
è	232	138	201
ï	239	139	221
î	238	140	209
ì	236	141	217
Ä	196	142	216
Å	197	143	208
É	201	144	220
æ	230	145	215
Æ	198	146	211
ô	244	147	194
ö	246	148	206
ò	242	149	202
û	251	150	195
ù	249	151	203

Char	Latin-1	PC-850	Roman-8
Ö	214	153	218
Ü	220	154	219
ø	248	155	214
£	163	156	187
Ø	216	157	210
á	225	160	196
í	237	161	213
ó	243	162	198
ú	250	163	199
ñ	241	164	183
Ñ	209	165	182
¿	191	168	185
¡	161	173	184
¤	164	207	186
ß	223	225	222
`	175	238	176
′	180	239	168
§	167	245	189
°	176	248	179
Umlaut	168	249	171

When run in Japanese mode, HTBasic allows the user to load a Japanese character set for use with the LABEL command. This is not done by default because of its memory requirements; the Japanese character set contains several thousand characters.


Defining Your Own LABEL Characters

To define your own characters, use one of these two syntaxes:

CONFIGURE LABEL First_char TO String$
CONFIGURE LABEL First_char TO Array$(*)

where First_char is a numeric expression, rounded to an integer, which gives the LABEL character to be defined, and String$ is a string expression that contains the new definition. If a string array is specified, then one definition is stored in each element and additional characters following First_char are also defined. Characters in the range 33 to 255 may be defined.

HTBasic provides 8 kilobytes (UNIX and Windows versions) or 2.5 kilobytes (DOS version) of definition space. If you run out of space, you can free up space by deleting unused definitions. To delete the definition of a character, specify a zero length string for the definition.

The LABEL font is defined in a character cell that is 8 units wide and 16 units high. The x units are numbered 0 to 7; the y units are numbered 0 to 15. The baseline is y=5. The normal descender, such as that for the lower-case "g", goes down to y=1. Characters are left justified in the character cell. The top of an H is at y=14. The right side of the H is at x=6.

Each character in the definition gives an x,y coordinate and a flag indicating whether to move or draw to that coordinate. The flag is stored in bit 7 of the character. If set, MOVE to x,y; otherwise DRAW to x,y. The x coordinate is stored in bits 6, 5, and 4. The y coordinate is stored in bits 3, 2, 1, and 0.

The following example shows the definition of the character "H":

Val = Move+ x*16 + y
133 = 128 + 0*16 + 5
14  =       0*16 + 14
238 = 128 + 6*16 + 14
101 =       6*16 + 5
138 = 128 + 0*16 + 10
106 =       6*16 + 10

CONFIGURE LABEL 72 TO CHR$(133)&CHR$(14)&CHR$(238)&
  CHR$(101)&CHR$(138)&CHR$(106)


Using LABELCHR.BAS

An example program, LABELCHR.BAS, is distributed with HTBasic that can be used to examine the definitions of characters, or develop new definitions. LABELCHR.BAS will not fully automate the task of adding characters, but is presented as an aid in developing character definitions.

When you run LABELCHR.BAS the screen will be painted with four grids. Grid #1 will be blank and is the current grid. Grid #2 displays an ASCII table of existing LABEL definitions for characters in the range 128 to 255. (The grid is actually too small to enclose all the characters. It is normal for the last row and last column to be displayed outside of the grid.) Grid #3 displays the letter "g", a good example of where a descender is located in the character cell. Grid #4 displays the letter "H", a good example of where an uppercase letter is located in the character cell.

The softkey menu displays the available choices. Softkey 1 is "Digitize Char", 2 is "Display Char", 3 is "Which Grid?", 4 is "Erase ON/OFF", 5 is "Show Chars", and 8 is "EXIT". Pressing "EXIT" will cause the program to end; control is returned to the BASIC system. Pressing "Which Grid?" will specify one of the four grids as the current grid. Pressing "Show Chars" will display an ASCII table in the current grid. The table is just like the one displayed in grid 2 at start up, unless you have changed some character definitions.

Pressing "Display Char" will display a character in the current grid. You will be asked to input the character you wish to display. Type the character and hit ENTER, or type the NUM of the character and hit ENTER. Depending on the Erase Flag, the character will be displayed on a fresh grid, or it will be displayed on top of the old contents of the grid. This capability is useful when building a new definition based on existing characters.

Pressing softkey 4, the "Erase ON/OFF" flag is toggled between ON and OFF. When ON, the current grid is cleared before each character is displayed. When OFF, the current grid is overlaid with each displayed character. An asterisk, "*", is displayed next to the ON or OFF to show the current state of Erase.

Pressing "Digitize Char" allows you to construct a new character definition. Typically, you would display in one or more of the grids whatever characters will assist you in creating a new definition, and then you would display in the current grid a character that is most like the new one you wish to define. Then you would press "Digitize Char" and begin digitizing the new character. You may use a mouse, or the arrow keys to move the cursor in the grid.

When using a mouse, move the cursor to the desired coordinate and then press the left button to Draw or the right button to Move there. Click either mouse button with the cursor outside the grid to end the definition. If using the arrow keys, move to the location you wish to Move/Draw to and press ENTER. The softkey menu will change, displaying "Draw", "Move", and "Digitize Done". Press "Move" or "Draw". When you are done, press ENTER and then "Digitize Done".

As each point is digitized, the correct value to use in CHR$ is printed on the display line. You should write these values down and use them when constructing your definitions. When you are done digitizing a character you are given the option of immediately assigning it to a character. If you wish to do so, enter the NUM of the character; if you do not wish to do so, enter -1 for the NUM. If you immediately define the character, you can then see it using "Display Char" or "Show Chars". The definition lasts until you QUIT HTBasic.


Installing DOS Code Page Support

Code page support is for DOS version of HTBasic only; users of other versions can skip to the next section. DOS users should read your DOS manual for a full explanation of code page installation and usage. For MS-DOS 5.0, see Chapter 13, "Customizing for International Use," in the MS-DOS User's Guide. For PC-DOS 4.0, see Chapter 7, "Using Code Page Switching," of the Using DOS 4.0 manual. For MS-DOS 4.0, see Appendix E, "How to Use Code Pages," of the MS-DOS User's Reference. Also read the information given in other places in the manual for each individual command summarized below. These summaries are given here for reference only.


COUNTRY

This command tells DOS what conventions to use for display of date, time, currency symbols, etc. In DOS 4.0 (and later revisions) it also specifies lexical order and capitalization, but these features are not used by HTBasic. HTBasic uses LEXICAL ORDER IS instead.


DEVICE

This command is used to load DISPLAY.SYS and PRINTER.SYS, device drivers for code page support of displayed character sets and printed character sets. In the command

DEVICE=DISPLAY.SYS CON=(xxx,yyy,z)

"xxx" should be the display type. Currently (for DOS 4.0 and 5.0), it should be "EGA" for both an EGA or a VGA. The CGA and Hercules are not supported. "yyy" should be 437, the code page number of the character set in the ROM of your display card. The "z" parameter specifies how many code pages, besides the one in ROM, you will be using. This is usually one, since you usually use only one code page besides 437.

If your printer type is supported by PRINTER.SYS, it can automatically load the correct character set into the printer when the code page is prepared or changed.

Note: DUMP ALPHA with the CRTB display driver (PLOTTER IS 6) active sends the ALPHA screen to the printer using the printer's graphic capabilities and will dump the screen correctly, even if PRINTER.SYS does not support your printer.


GRAFTABL

This command is needed if you have a CGA display to display characters above CHR$(127) correctly in graphics mode. In text mode, the hardware is limited to code page 437.


NLSFUNC

This command loads information from COUNTRY.SYS and enables the use of CHCP.


MODE

This command communicates with the device drivers loaded by DEVICE. The MODE xxx CODEPAGE PREPARE command (which can be abbreviated MODE xxx CP PREP) must be used to prepare each code page that will be used on each device. This should be done before KEYB.


KEYB

This command loads the keyboard driver for international keyboards. One of our customers reported that using KEYB decreases the maximum reliable baud rate. They solved the problem by booting without KEYB. The problem can also be solved by using hardware handshaking or by using a faster computer. We don't know what version of DOS they were using. This is the kind of bug that Microsoft would probably be interested in fixing since it affects all programs using serial interrupts. If you experience this problem, please contact Microsoft.


CHCP

This command is used to select or change the current code page. It informs the drivers for the keyboard, display, and printers of the change. It is equivalent to informing each driver individually of the change using MODE CON CP SELECT, MODE PRN CP SELECT, and KEYB commands.


Examples

The following two examples are representative only. If your configuration works, there is no reason to change it. However, if your configuration does not work, these examples will be helpful since they have been tested and are known to work. Use them as a known starting point.

The following example shows the CONFIG.SYS and AUTOEXEC.BAT commands, in the correct order, to install code page 850 support in MS-DOS 3.3 with a German keyboard. No printer driver is installed. The files COUNTRY.SYS, DISPLAY.SYS, EGA.CPI, and KEYBOARD.SYS should be in the C:\DOS directory. A path should be established to the NLSFUNC, MODE, and KEYB commands before they are executed, or they should be in the root directory.

CONFIG.SYS
country=049,,c:\dos\country.sys
device=c:\dos\display.sys con=(ega,437,1)

AUTOEXEC.BAT
nlsfunc
mode con codepage prepare=((850) c:\dos\ega.cpi)
keyb gr,,c:\dos\keyboard.sys
chcp 850

The following example shows the code page related commands installed by the PC-DOS 4.0 INSTALL/SELECT program. Again, German is the language installed. Code page 850 is prepared for use, but code page 437 is made active. KEYB and NLSFUNC are executed in CONFIG.SYS rather than AUTOEXEC.BAT using the DOS 4.0 INSTALL command. All the necessary files are placed in the necessary places by the INSTALL/SELECT program.

CONFIG.SYS
COUNTRY=49,,COUNTRY.SYS
DEVICE=DISPLAY.SYS CON=(EGA,437,1)
INSTALL=KEYB.COM US,,KEYBOARD.SYS
INSTALL=NLSFUNC.EXE COUNTRY.SYS

AUTOEXEC.BAT
MODE CON CP PREP=((850) EGA.CPI)
KEYB GR,,KEYBOARD.SYS
CHCP 437


User-Defined Lexical Orders

The lexical order rules provided with HTBasic are sufficient for most uses. But if needed, you may define your own rules. The lexical order of each character may be specified. Also, because the lexical order of some languages treat some letters as if they were two, treat some two-letter combinations as if they were one, and ignore some letters, you may define certain special cases to handle these situations. User-defined lexical rules are stored in an array and are activated with the statement:

LEXICAL ORDER IS Array(*)

When user-defined rules are in effect, SYSTEM$("LEXICAL ORDER IS") returns "USER DEFINED".


Order Table

The main part of user-defined lexical order rules is stored in an order table, which is the first 256 elements of the array. These elements specify the lexical order for each CHR$ from 0 to 255. The order number is stored in the upper byte of each element. For example, to assign lexical order number 0 to the letter "A", and lexical order 1 to the letter "B":

10  INTEGER A(0:256)
20  A(NUM("A"))=SHIFT(0,-8)
30  A(NUM("B"))=SHIFT(1,-8)

When "A" is compared to "B", it will be smaller, since 0 is smaller than 1. "A"<B" returns 1.

Any special cases (2-to-1, 1-to-2, ignore) are noted in the lower byte of each element, and if additional information is needed it is stored in a "Special Case" table that follows after the first 256 elements of the array.

The lower byte of each element in the order table may have a value from 0 to 255. The meaning of each value is given in the following table:

Value	Meaning
0	No special case.
1	Ignore this character.
64+index	2-to-1 translation might be needed on this character.
128+index	Perform 1-to-2 translation.
192-255	Sub-order number exists for this character.

In the above table, "index" is a value from 0 to 63 and specifies an index into the special case table.


Special Case Table

The length of the special case table is stored in the 257th element of the array and can be from 0 to 64 elements. The length must be stated, even if it is zero. Thus, the smallest the array specified in the LEXICAL ORDER IS statement can be is 257 elements.

The special case table starts with the 258th element of the array, which is the element immediately following the length. An index of 0 specifies the 258th element of the array.

Note: In the example, the BASE of the array was 0, and so the 258th element of the array is A(257). Thus, index 0 in the special case table is A(257). If the BASE of the array had been another value, the element number for the start of the special case table would have been different, but still at the 258th element.


Ignore Characters

To expand on our previous example, let's specify that the letter "C" be ignored:

40  A(NUM("C"))=1
100 A(256)=0

Now "ABC" will be equal to "AB" and "C" will be equal to "". You can see from line 100 that we have also specified a zero length special case table. As we add to our example, we will add to line 100. Because the array A(*) has been declared with a length of 257 characters, the array declaration in line 10 will also have to be changed as we add special cases.


2-to-1 Translation

A 2-to-1 translation takes a two character combination, and translates it to one character. Note: The strings involved are not actually changed. The change occurs internally for the string comparison and is then discarded.

To define 2-to-1 translations starting with a certain character, the order table entry for the starting character is used to store three things: 1) the order number is stored in the upper byte for use when the character occurs, but not as part of a two character combination, 2) the value 64 is stored in the lower byte to indicate that this character is the first character of one or more 2-to-1 translations, 3) an index into the special case table is stored in the lower byte.

The index into the special case table points to a list of two character combinations that all start with the same first character. The first entry in the list gives the number of two character combinations in the list. The remaining entries give the second character of each two character combination and the order number to use in place of the combination. The second character is given in the upper byte and the order number is given in the lower byte.

Note: The first character was given in the order table and need not be repeated in the special case table. Only the second character of each combination is given in the special case table.

For example, we might want to consider "DX" to be a single character with order number 4 and "DY" to be a single character with order number 3. For all other occurrences of the letter "D" we want "D" to have order number 2. For our example,

10  INTEGER A(0:259)
50  A(NUM("D"))=SHIFT(2,-8)+64+0
100 A(256)=0+3
110 A(257)=2
120 A(258)=SHIFT(NUM("X"),-8) + 4
130 A(259)=SHIFT(NUM("Y"),-8) + 3

Line 50 is the order table entry for the letter "D". Order number 2 will be used for "D" unless it is "DX" or "DY". The value 64 indicates one or more 2-to-1 translations exist that start with the letter "D". The value 0 is the index into the special case table.

Line 100 is the length of the special case table. Previously in our example, we had set it to zero, but we are now adding three entries to the special case table.

In line 110, A(257) is at index 0 in the special case table. This is the start of our list of two character combinations beginning with "D". Since we have two, "DX" and "DY", we set A(257) to two.

Lines 120 and 130 define "DX" and "DY" to have order numbers 4 and 3. Now the following will both be true:

"DY" <"DX" - because 3 <4
"DZ" <"DX" - because 2 < 4 ("D" < "DX").


1-to-2 Translation

A 1-to-2 translation takes a single character and translates it into two characters. This capability also includes intelligent handling of upper and lowercase. For example, if "E" is to be translated to "FG" then "Exyz" should be translated to "Fgxyz", while "EXYZ" should be translated to "FGXYZ".

Note: The strings involved are not actually changed. The change occurs internally for the string comparison and is then discarded.

To define 1-to-2 translations for a certain character, the order table entry for the character is used to store three things: 1) the first order number is stored in the upper byte, 2) the value 128 is stored in the lower byte to indicate a 1-to-2 translation, 3) an index into the special case table is stored in the lower byte.

The special case table entry contains the second order numbers for both upper and lowercase. The lower byte contains the lowercase order number, while the upper byte contains the uppercase order number. The uppercase order number is used if the initial character is uppercase and is not followed by a lowercase character.

For our example, if we want to use an order number of 5 for "F", 6 for "G", and 37 for "g", then:

10  INTEGER A(0:260)
60  A(NUM("E"))=SHIFT(5,-8)+128+3
100 A(256)=0+3+1
140 A(260)=SHIFT(6,-8) + 37

Line 100 is the length of the special case table. Previously in our example, we had set it to three, but we have now added one more entry to the special case table.

Line 60 is the order table entry for the letter "E" and line 140 is the special case entry for "E". In place of "E", two order numbers will be used, 5 and 37 for "Fg", or 5 and 6 for "FG". Now the following will all be true:

"E" > "FD"
"E" = "FG"
"E" < "FH"
"EXYZ" = "FGXYZ"
"Exyz" = "Fgxyz"


Sub-Order Numbers

Sometimes it is useful to assign several characters the same order number, yet still collate them in a specific order. For example, it might make sense to assign all occurrences of "E", regardless of the accent, the same order number, but still allow them to be collated in a specific order. This can be accomplished using sub-order numbers. Sub-order numbers can range from 0 to 63. To assign a sub-order number to a character, set the lower byte of the order table entry to the sub-order value plus 192.

When strings are compared, if the order numbers of two characters are the same, the sub-order numbers are used to determine the lexical order. If a sub-order number has not been explicitly assigned to a character, 0 is used. A sub-order number can not be assigned to characters that are used in Ignore, 2-to-1, or 1-to-2 translations since the lower byte of the order table entry is already used.

As an example of sub-order number usage, say we wish to give "H" and "I" the same order number, 7, but wish "H" to collate before "I" using sub-order numbers. We can give "H" a sub-order number of 0 and "I" a sub-order number of 1:

80 A(NUM("H"))=SHIFT(7,-8)+192+0
90 A(NUM("I"))=SHIFT(7,-8)+192+1


Putting User-Defined Rules Into Effect

An order number must be assigned to each value, 0 through 255, in the order table. Once this has been done, as well as assigning all special cases, the array may be specified in a LEXICAL ORDER IS statement to make it take effect. All of the user-defined order rules explained above are compatible between HTBasic and HP BASIC. HTBasic extensions to LEXICAL ORDER IS that allow user-defined upper and lowercase conversions are explained in the following paragraphs.

But first, let's complete our example:

5    REM USERDEF.BAS
10   INTEGER A(0:260)
20   A(65)=0
30   A(66)=256
40   A(67)=1
50   A(68)=576
60   A(69)=1411
65   A(70)=1280
75   A(71)=1536
80   A(72)=1984
90   A(73)=1985
100  A(256)=4
110  A(257)=2
120  A(258)=22532
130  A(259)=22787
140  A(260)=1573
150  FOR I=74 TO 255
160    A(I)=SHIFT(I-66,-8)
170  NEXT I
180  FOR I=0 TO 64
190    A(I)=SHIFT(I+190,-8)
200  NEXT I
210  LEXICAL ORDER IS A(*)
220  END

We have added lines 65, 75, and 150 to 200 to assign the characters that were not yet assigned. We have also sped up the program by pre-evaluating functions like NUM("A") and SHIFT(0,-8) wherever possible. Finally, line 210 causes all the changes to take effect.


User-Defined UPC$/LWC$ Rules

In addition to specifying order rules, HTBasic has been enhanced to let you specify upper and lowercase conversion rules as well. This capability is an extension to HTBasic and will not work if used with HP BASIC. However, HP BASIC will not return an error; the UPC$/LWC$ rules will simply be ignored.

Note: There is some danger in specifying meaningless upper/lowercase rules because HTBasic uses these rules in checking the syntax of a command or program line. For example, when you type "RUN", UPC$("RUN") is compared against the list of known statements. As long as you take reasonable care in defining your rules, you shouldn't have any problems.

Upper/lowercase rules are stored in the LEXICAL ORDER IS array immediately following the special case table. The UPC$/LWC$ table consists of 257 elements. The first element must have the value 21576 to indicate that the UPC$/LWC$ table is present. The rules themselves are stored in the next 256 elements, one for each possible character. All 256 characters must be defined. In each element, the upper byte contains the UPC$ value and the lower byte contains the LWC$ value.

For example, in the USERDEF.BAS example above, the special case table ends at element A(260). Element A(261) should be assigned a value of 21576 if upper/lowercase rules are also being specified. Elements A(262) through A(517) would contain the rules for CHR$(0) through CHR$(255). To set the UPC$/LWC$ values for "A" and "a", the following statements would be used:

A(257+A(256))=21576
A(258+A(256)+NUM("A"))=SHIFT( NUM("A"),-8)+NUM("a")
A(258+A(256)+NUM("a"))=SHIFT( NUM("A"),-8)+NUM("a")

The subscript calculation in this example deserves some explanation. If the array BASE is zero then A(256) is the length of the special case table, 257+A(256) is the first element after the special case table, and 258+A(256)+NUM("x") is the UPC$/LWC$ definition for "x".

Of course, it is best to simplify these statements to:

A(261)=21576
A(327)=16737
A(359)=16737


Example Data Files

If you installed the optional LEXICAL ORDER files during installation, the in the LEXICAL subdirectory in the HTBasic directory there are several examples of user-defined LEXICAL ORDER IS tables that change both the order rules and the upper/lowercase rules. The files that are included depend on the version of HTBasic. Files for code page 850 have filenames of PC*.LEX. Files for Roman-8 have filenames of R8*.LEX. Files for the out-dated version of Roman-8 used by HP BASIC are stored in files with names HP*.LEX. Files for Latin-1 have filenames of L1*.LEX.

The file LEXICAL.BAS contains a SUB named "Lexical" that can be used to load the tables stored in these files. (This SUB is listed earlier in this chapter.) Line 50 specifies PC*.LEX files stored in the C:\HTB directory, but you may change this line to fit your needs.


Roman-8 Character Set Support

Although Roman-8 is a fairly popular character set, especially among users of the European-language versions of HP BASIC, it is not available under DOS, Windows and most non-HP versions of UNIX. Since HTBasic depends upon the operating system for character set support, you should convert from Roman-8 to the native character set of your computer. A conversion program is presented in the next section.

If you must use the Roman-8 character set, the sections following the translation program section describe solutions that give most of the capabilities needed. To use a different character set you must 1) change the character set used by the display, 2) change the character set produced by the keyboard, 3) change the lexical order rules, and 4) change the LABEL character definitions.


Roman-8 Translation Program

An example program, HP2PC.BAS, is distributed with HTBasic that can be used to translate ASCII files (including program files saved in ASCII) from the Roman-8 character set to code page 850 or Latin-1. The program only translates characters that appear literally or in CHR$(xxx) statements, where "xxx" is a constant above 127. If a character is specified in any other way (for example, "CHR$(X+3)"), it is not translated. You will have to make those translations manually.

If any attribute control characters in the range CHR$(128) to CHR$(143) are seen, they are translated to the alternate range at CHR$(16) to CHR$(31) and you must add the following statement to make attribute characters be recognized in this new range:

CONTROL CRT,100;1

Several characters that exist in the Roman-8 character set are not found in code page 850 or Latin-1. When translating to code page 850, the characters in the range CHR$(144) to CHR$(160) are translated to CHR$(219), a rectangular block, to make them easy to spot and hand translate. When translating to Latin-1, the characters in the range CHR$(144) to CHR$(160) are unchanged and the Dutch guilder symbol "ˆ", CHR$(190), is translated to "*", CHR$(42), to make it easy to spot and hand translate. Other characters are translated to similar characters:

From...	To...
Character	Roman-8	Character	PC-850	Latin-1
Grave accent	169	`	96	96
Circumflex	170	^	94	94
Tilde	172	~	126
Lira	175	£	156	163
 	235	S	83	83
 	236	s	115	115
 	238	Y	89	89

To translate to code page 437, specify code page 850. The only difference is the translation for CHR$(191), the "¢" symbol. It is translated to CHR$(189) which is correct for code page 850, but should be CHR$(155) for code page 437. This minor correction can then be done by hand.


DOS Display Font

HTBasic includes a font loader program, LOADFNT, that can load the Roman-8 character font into the EGA or VGA display hardware. Note that changing the display font without changing the keyboard font causes a mismatch for characters above CHR$(128). CONFIGURE KBD, explained below, can correct this situation for the most part.

See the Installing and Using the DOS Version manual for more information on LOADFNT.  The CGA and the Hercules Monochrome Graphics Adapters have their character fonts defined in hardware and cannot be changed. The Roman-8 font is stored in a file named HP200.FNT. The following example loads this file, assuming it is in the C:\HTB directory:

C>LOADFNT C:\HTB\HP200.FNT

This command can be placed in the AUTOEXEC.BAT file so that it is automatically loaded every time DOS is started. Once loaded, the Roman-8 font is used for all applications, which may not be desirable. To disable the Roman-8 font use:

C>LOADFNT OFF

To re-enable it, use:

C>LOADFNT ON

Note: LOADFNT is not compatible with code page support, and may be ignored if code page drivers are installed.


Windows Display Font

A Windows font containing the Roman-8 character set, ROMAN8.FON, is supplied with the Windows version of HTBasic. To install the Roman-8 font, select Control Panel, Fonts, and Add.... Then change the drive and directory to LEXICAL subdirectory of the HTBasic directory (HTBWIN, be default). Then select Roman8 and OK. Roman8 should then be accessible to any Windows program that uses fixed width fonts.

To select Roman8 for use with HTBasic, use the -fn command line switch, explained in the Installing and Using the Windows Version manual. Basically, select Program Manager, TransEra HTBasic, File, Properties, and add "-fn Roman8" to the command line. For example,

C:\HTBWIN\HTBWIN.EXE -fn Roman8

Note that changing the display font without changing the keyboard font causes a mismatch for characters above CHR$(128). CONFIGURE KBD, explained below, can correct this situation for the most part.


Keyboard

The statement CONFIGURE KBD has been added to HTBasic to allow simple keyboard character set re-mapping. (This is different than CONFIGURE KEY, which re-maps function and editor keys.) CONFIGURE KBD is not a complete keyboard driver. It uses a look-up table to translate characters from one character set to another.

The files PCTOR8.KBD (formerly HP200.KBD) and L1TOR8.KBD contain the necessary keyboard re-mappings from code page 850 and Latin-1 to Roman-8. The following program will set up the re-mapping. Use either PCTOR8 or L1TOR8 in line 60, depending on the character set in use by the operating system keyboard driver. Where no translation exists for a character, CHR$(252) is returned.

10   !SETKBD.BAS
20   DIM Pc2hp$[256]
30   CLEAR SCREEN
40   PRINT "Set up translation string to Roman-8"
60   ASSIGN @Io TO "PCTOR8.KBD" !Use L1TOR8 for Latin-1
70   ENTER @Io;Pc2hp$
80   ASSIGN @Io TO *
90   CONFIGURE KBD 0 TO Pc2hp$
100  END

To enter a character without re-mapping, use the ANY CHAR function.

The syntax of the CONFIGURE KBD statement is:

CONFIGURE KBD First_char TO String$

where First_char is a numeric expression, rounded to an integer, that gives the first keyboard character to be re-mapped, and the first character in String$ gives the display character that it is re-mapped to. If the length of String$ is longer than one, then additional characters following First_char are also re-mapped.


Roman-8 LEXICAL ORDER
LEXICAL ORDER

Only the HP 700 Workstation version of HTBasic has built-in lexical order rules for the Roman-8 character set. When using Roman-8 with other versions, you must load LEXICAL ORDER rules from data files. The data files are named:

Language	File
ASCII	R8ASCII.LEX
FRENCH	R8FRENCH.LEX
GERMAN	R8GERMAN.LEX
SPANISH	R8SPANIS.LEX
SWEDISH	R8SWEDIS.LEX

The SUB "Lexical", listed previously in this chapter and stored on the distribution disks in the file LEXICAL.BAS, can be used to set the LEXICAL ORDER using these files. Change line 50 to specify "R8" instead of "PC" and change the directory as necessary:

50  A$="C:\HTB\R8"&L$[1;6]&".LEX"


LABEL

The CONFIGURE LABEL statement must be used to define characters above 127 so that they match the Roman-8 character set. CONFIGURE LABEL is explained earlier in this chapter.


LEXICAL ORDER Tables

The following pages contain LEXICAL ORDER tables for FRENCH, GERMAN, SPANISH and SWEDISH. Different tables are presented for code page 850, Roman-8 and Latin-1 character sets. No tables are given for ASCII because when the LEXICAL ORDER IS ASCII, regardless of the character set the order number is the same as the NUM of each character.

For code page 850 and the Latin-1 character sets, the order number for each character was chosen according to the following guidelines: If the character existed in the Roman-8 character set, it is given the same order number it had under HP BASIC. New alphabetic characters were added in alphabetical order. New symbol characters were added after CHR$(127) and given sequentially increasing order numbers.

The order numbers for Roman-8 differ slightly than those in HP BASIC. This is because several characters have been added to Roman-8 since HP BASIC was created. The new characters are 177, 178 and 242 to 245.

Each table contains the Order number, the NUM, and the CHR$ for each character. If the character is ignored during comparisons, the order will be blank. For two-character combinations that have a single order number, the two characters are given in the Chr$ column, but no Num is listed. For characters that are expanded into two characters, the two characters are listed in the Order column. If the original character is uppercase, two expansions are listed. Remember that two order numbers are produced, not just one. If the character has a sub-order number, it is given following a decimal point in the Order column.


Character Set Tables

The following pages contain character set and LEXICAL ORDER tables for code pages 850, 437, Roman-8 and Latin-1 character sets.


Code Page 437 Character Set

Please see the printed manual for the table.


Code Page 850 Character Set

Please see the printed manual for the table.


LEXICAL ORDER IS FRENCH    (Code Page 850)

Please see the printed manual for the table.


LEXICAL ORDER IS GERMAN   (Code Page 850)

Please see the printed manual for the table.


LEXICAL ORDER IS SPANISH   (Code Page 850)

Please see the printed manual for the table.


LEXICAL ORDER IS SWEDISH  (Code Page 850)

Please see the printed manual for the table.


Roman-8 Character Set

Please see the printed manual for the table.


LEXICAL ORDER IS FRENCH (Roman-8)

Please see the printed manual for the table.


LEXICAL ORDER IS GERMAN (Roman-8)

Please see the printed manual for the table.


LEXICAL ORDER IS SPANISH (Roman-8)

Please see the printed manual for the table.


LEXICAL ORDER IS SWEDISH (Roman-8)

Please see the printed manual for the table.


Latin-1 Character Set

Note in the table below, CHR$(145) and CHR$(146) are extensions to Latin-1 found in Windows fonts and may not be present in other implementations of Latin-1, such as those found on the Sun SPARCstation.

Please see the printed manual for the table.


LEXICAL ORDER IS FRENCH (Latin-1)

Please see the printed manual for the table.


LEXICAL ORDER IS GERMAN (Latin-1)

Please see the printed manual for the table.


LEXICAL ORDER IS SPANISH (Latin-1)

Please see the printed manual for the table.


LEXICAL ORDER IS SWEDISH (Latin-1)

Please see the printed manual for the table.


ISO-932 Character Set

Note in the table below, the characters marked with diamonds are taken to be introductory bytes for two-byte Shift-JIS characters.

Please see the printed manual for the table.


Overview of the Shift-JIS Character Set

The table below shows the categories of two-byte characters in the Shift-JIS character set. The range values are in hexadecimal. The second byte in a Shift-JIS character may have values between hexadecimal 40 and FC, excluding 7F.

Range	Type of character
8140-81FC	Symbols

8240-824E	undefined
824F-8258	Digits
8259-825F	undefined
8260-8278	Uppercase Roman letters
8279-8280	undefined
8281-8299	Lowercase Roman letters
829B-829E	undefined
829F-82F1	Hiragana
82F2-82FC	undefined

8300-8396	Katakana
8397-839E	undefined
839F-83B6	Uppercase Greek letters
83B7-83BE	undefined
83BF-83D6	Lowercase Greek letters
83D7-83FC	undefined

8440-8461	Uppercase Russian Cyrillic
8462	undefined
8463-8491	Lowercase Russian Cyrillic
8492-849E	undefined
849F-84BE	Box drawing
84BF-84FC	undefined

85xx-86xx	undefined

8740-879C	symbols
879D-97FC	undefined

8840-889E	undefined
889F-8FFC	Level 1 kanji

89xx-9872	Level 1 kanji

Range	Type of character
9873-989E	undefined

989F-9FFC	Level 2 kanji

E0xx-EFxx	Level 2 kanji

F0xx-FCxx	Level 3 kanji (undefined in most
 implementations)

The level 1 kanji are arranged in the order of the hiragana representations of their most common on pronunciation. The level 2 and level 3 kanji are arranged in order of the stroke count of their principal radical followed by the stroke count of the remaining portion of the character.

All two-byte characters, including the Roman, Greek, and Russian characters, are twice as wide when displayed as the one-byte characters. The HTBasic CVT$ function can convert between one- two-byte Roman and katakana characters.

Note that voiced katakana and hiragana characters are represented by a single two-byte character in the shift-JIS character set while they are represented by a one-byte character plus a separate one-byte voicing mark in the ISO-932 character set.